Code Wars II - Array Helpers - Solving the kata

in STEMGeeks5 months ago

As we saw in the previous article, in order to solve this exercise, first of all we must declare a non-nested and non-generic class. Let's also remember that the class must be static. Let's see what happens if we declare an extension method in a non-static class:

Como vimos en el artículo anterior, para resolver este ejercicio, primero que todo debemos declarar una clase no anidada y no genérica. Recordemos además que la clase debe ser estática. Veamos que ocurre si declaramos un método de extensión en una clase no estática:

If we place the mouse over the red underline that appears under the class name, we will see that Visual Studio Code throws the following error message: An extension method must be defined in a non-generic static class (CS1106). Clicking the link we will get to the Compiler Error CS1106 page: Extension methods must be defined in a non-generic static class. The extension methods must be defined as static methods in a non-generic static class.

Si colocamos el mouse sobre el subrayado rojo que nos aparece debajo del nombre de la clase, veremos que Visual Studio Code nos lanza el siguiente mensaje de error: Un método de extensión debe definirse en una clase estática no genérica (CS1106). Siguiendo el enlace llegaremos a la página Compiler Error CS1106: Los métodos de extensión deben definirse en una clase estática no genérica. Los métodos de extensión deben definirse como métodos estáticos en una clase estática no genérica.



Since we must extend the Array class, we have to indicate it in the first parameter of our extension method, by putting the this keyword first. This parameter will not be necessary in the call, as long as the call is made from the extended class.
Due to their similarities, I have grouped the methods in groups of two. For the Square() and Cube() methods the modus operandi is the same. We must take the array and iterate over it and at each iteration, we must find the square or cube of the corresponding element. We could very well do the following:

Ya que debemos extender la clase Array, tenemos indicarlo en el primer parámetro de nuestro método de extensión, antecediéndolo con la palabra reservada this. Este parámetro no será necesario en la llamada, siempre y cuando dicha llamada se haga desde la clase extendida.
Para la siguiente explicación, he agrupado los métodos en grupos de a dos, debido a sus similitudes. Para los métodos Square() y Cube() el modus operandi es el mismo. Debemos tomar la matriz y recorrerla y, a cada vuelta de bucle, hallarle el cuadrado o el cubo al elemento correspondiente. Pudiéramos perfectamente hacer lo siguiente:



But let's remember that the exercise put a small restriction: the original array must not be changed in any case! Since arrays work by reference, we would be modifying the original array, since both would point to the same memory space. We must assign the result to a new array, as follows:

Pero recordemos que el ejercicio nos ponía una pequeña restricción: la matriz original no debe ser cambiada bajo ninguna circunstancia! Ya que los arrays funcionan por referencia, estaríamos modificando el array original, pues ambos apuntarían al mismo espacio en memoria. Debemos asignar el resultado de las operaciones a un nuevo array, como sigue:



For the Average() and Sum() methods we proceed in the same way, we iterate over the array and, in this case, at each iteration we store the sum in a variable. I could have reused code and used the Sum() method inside the Average() method, as suggested by user Zooram in his solution, but I didn't realize it at the time.
The difference is that for Average() we are asked that in case the array is empty, NaN is returned, since the size of the array in that case would be 0 and the division by 0 is not defined. We do this by accessing the Double.NaN field. Finally we divide the result of the sum by the size of the array and return it. Remember that in C# only dividend or divisor must be double for a decimal division to be performed. If both are type int and the division is not exact, a loss of information will occur and C# will remove all decimal digits from the division quotient to maintain type consistency and return a type int result. In addition, after this it would be converted back to double automatically, since Average() return data type is indeed double and C# allows the implicit conversion from int to double.

Para los métodos Average() y Sum() procedemos de la misma manera, recorremos el array y, en este caso, a cada vuelta de bucle vamos almacenando la suma en una variable. Podía haber reutilizado código y haber usado el método Sum() dentro del método Average(), tal y cómo sugería el usuario Zooram en su solución, pero no me di cuenta en el momento.
La diferencia es que para Average()nos piden que en caso de estar vacío el array, se devuelva NaN, ya que el tamaño del array en ese caso sería 0 y la división por 0 no está definida. Hacemos esto accediendo al campo Double.NaN. Finalmente dividimos el resultado de la suma entre el tamaño del array y lo devolvemos. Recuerda que en C# sólo basta con que al menos uno, dividendo o divisor, sea de tipo double para que se realice una división decimal. Si ambos son de tipo int y la división no es exacta, ocurrirá una pérdida de información y C# por detrás eliminará todas las cifras decimales del cociente de la división para mantener la coherencia de tipos y devolver un resultado también de tipo int. Igualmente, luego de tener efecto dicha pérdida de información, se convertiría de vuelta a double de manera automática, ya que el tipo de dato de retorno de Average() es precisamente double y C# permite la conversión implícita desde int hacia double.



Finally the Even() and Odd() methods. Since we do not know how many odd or even values the array contains, we use a dynamic structure to store those values. We iterate over the array and filter those values making use of a simple condition: that the remainder of the division by 2 is 0 for even and 1 for odd numbers. Then we simply use the ToArray() method of the generic List<T> class to convert the list into an array and return it.

Por último los métodos Even() y Odd(). Como no sabemos cuantos valores pares o impares contiene el array, utilizamos una estructura dinámica para almacenar esos valores. Recorremos el array y filtramos los valores haciendo uso de una sencilla condición: que el resto de la división entre 2 sea 0 para los pares y 1 para los impares. Luego simplemente utilizamos el método ToArray() de la clase genérica List<T> para convertir la lista en un array y devolverlo.



And that's it for this exercise. In the next blog I will be analyzing at several alternative answers to mine and explaining them. I hope you enjoyed this article as much as I enjoyed writing it.

Y eso es todo para este ejercicio. En el siguiente blog estaremos viendo varias respuestas alternativas a la mía y explicándolas. Espero hayan disfrutado este artículo tanto como yo disfruté escribiéndolo.


Links [Enlaces]

Array Helpers | Codewars
https://www.codewars.com/kata/525d50d2037b7acd6e000534

This is my repository: Codewars-kata
https://github.com/Kirito0922/Codewars-kata/blob/4e913b40f656a68be2a5ac894ad17450b3996597/ArrayHelpers.cs

Compiler Error CS1106 - C# | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs1106?f1url=%3FappId%3Droslyn%26k%3Dk

C# Solution for Array Helpers by Zooram | Codewars
https://www.codewars.com/kata/reviews/657989825e40360001993dd0/groups/6588443ad3702a0001ede67d

Arithmetic operators - C# reference | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators

Built-in numeric conversions - C# reference | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions

Double.NaN Field (System) | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/api/system.double.nan?view=net-8.0



English translation made with DeepL Translate
Traducción al Inglés hecha con Deepl Translate

Sort:  

Congratulations @kirito0922! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You published more than 10 posts.
Your next target is to reach 20 posts.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

nice to know!!

Happy to show you something new