Seis métodos de matriz de Ruby que necesita saber

Las matrices son una de las estructuras fundamentales de la programación. Ser capaz de manipular y leer datos rápidamente es vital para tener éxito en la construcción de cosas con computadoras. Aquí hay seis métodos de los que no puede prescindir.

Mapa / cada uno

Estos dos métodos son muy similares. Le permiten recorrer "cada" elemento de una matriz y hacer algo con él.

Mira algún código:

array = [1, 2, 3] effects = array.each # create record from x  added = array.map x + 2 

Si leemos added, obtendremos [3, 4, 5]. Si leemos de effects, todavía obtendremos [1, 2, 3]. Aquí está la diferencia entre estos dos: .mapdevolverá una nueva matriz modificada, mientras .eachque devolverá la matriz original.

Efectos secundarios en el mapa

Si está acostumbrado a la programación funcional, Ruby .mappuede parecer muy extraño. Mira este ejemplo. Tengo una Eventclase simple en mi proyecto:

# we create an array of records 2.3.0 :025 > array = [e, e2, e3] => [#, #, #] # so far so good 2.3.0 :026 > new_array = array.map => [#, #, #] # uh-oh, that ain't right 2.3.0 :027 > array => [#, #, #]

Podríamos esperar que estemos trabajando con algún tipo de copia de nuestros registros en la matriz, pero no es así. Todo eso es solo para decir: ten cuidado. Puede crear fácilmente efectos secundarios en sus .mapfunciones.

Ok, descansa tranquilo, eso fue lo difícil. Navegación tranquila de aquí en adelante.

Seleccione

.selectle permite "encontrar" un elemento en una matriz. Tienes que dar .selectuna función que devuelva verdadero o falso, para que sepa si “conservar” o no un elemento de la matriz.

2.3.0 :028 > array = ['hello', 'hi', 'goodbye'] 2.3.0 :029 > array.selectword => ["hello", "goodbye"]

Un ejemplo un poco más complejo, probablemente acercándose a cómo lo usarías realmente. Agreguemos .mapal final por si acaso:

2.3.0 :030 > valid_colors = ['red', 'green', 'blue'] 2.3.0 :031 > cars = [{type: 'porsche', color: 'red'}, {type: 'mustang', color: 'orange'}, {type: 'prius', color: 'blue'}] 2.3.0 :032 > cars.select valid_colors.include?(car[:color]) .map  => ["porsche", "prius"]

Sí, amigos, pueden unirse a estos métodos para ejercer un poder inimaginable. Ok, probablemente puedas imaginarlo, pero sigue siendo genial.

Sintaxis aún más limpia: .map (&: método)

Si hubiéramos estado trabajando con objetos de automóvil y no solo con un simple hash, podríamos haber usado una sintaxis más limpia. Usaré un ejemplo diferente por brevedad. Quizás estemos preparando esta lista de autos para enviar en una API y necesitamos generar JSON. Podemos usar el .to_jsonmétodo:

# using regular map syntax 2.3.0 :047 > cars.select .map car.to_json => ["{\"type\":\"porsche\",\"color\":\"red\"}", "{\"type\":\"prius\",\"color\":\"blue\"}"] # using the cleaner syntax 2.3.0 :046 > cars.selectcar.map(&:to_json) => ["{\"type\":\"porsche\",\"color\":\"red\"}", "{\"type\":\"prius\",\"color\":\"blue\"}"]

Rechazar

Rechazar es el .selectyang del yin to :

2.3.0 :048 > cars.reject valid_colors.include?(car[:color]) .mapcar => ["mustang"]

En lugar de seleccionar los elementos de la matriz que queremos, rechazaremos todo lo que no haga que nuestra función sea verdadera. Recuerde que la función dentro de nuestro rechazo es lo que determina si el elemento de la matriz se devolverá o no; si es cierto, el elemento se devuelve, de lo contrario no.

Reducir

Reduce tiene una estructura más compleja que nuestros otros métodos de matriz, pero generalmente se usa para cosas bastante simples en Ruby, principalmente matemáticas. Tomaremos una matriz y luego ejecutaremos una función en cada elemento de esa matriz. Esta vez, nos preocupamos por lo que se devuelve de los otros elementos de la matriz . Normalmente estamos sumando un montón de números:

2.3.0 :049 > array = [1, 2, 3] 2.3.0 :050 > array.reduce => 6

Tenga en cuenta que podemos trabajar con cadenas de la misma manera:

2.3.0 :053 > array = ['amber', 'scott', 'erica'] 2.3.0 :054 > array.reduce sum + name => "amberscotterica"

Esto puede resultar útil si estamos viendo varios registros de trabajo. Si necesitamos sumar el total de horas trabajadas, o si queremos averiguar la suma de todas las donaciones del mes pasado. Una nota final sobre .reduce. si está trabajando con cualquier otra cosa que no sean números (o cadenas) antiguos, deberá incluir un valor inicial como argumento:

array = [{weekday: 'Monday', pay: 123}, {weekday: 'Tuedsay', pay: 244}] array.reduce(0)  => 367 array.reduce(100) sum, day => 467

Existen, por supuesto, formas más avanzadas de uso, .reducepero esto es suficiente para comenzar.

Unirse

Lo estoy agregando .joincomo un bono porque es muy útil. Usemos nuestros autos nuevamente:

2.3.0 :061 > cars.map car[:type].join(', ') => "porsche, mustang, prius"

.joines muy parecido, .reduceexcepto que tiene una sintaxis súper limpia. Toma un argumento: una cadena que se insertará entre todos los elementos de la matriz. .joincrea una cadena larga de lo que sea que le des, incluso si su matriz es un montón de cosas que no son cadenas:

2.3.0 :062 > cars.join(', ') => "{:type=>\"porsche\", :color=>\"red\"}, {:type=>\"mustang\", :color=>\"orange\"}, {:type=>\"prius\", :color=>\"blue\"}" 2.3.0 :065 > events.join(', ') => "#, #, #"

¿Por qué no juntarlo todo?

¡Usemos todos los métodos de matriz en esta publicación juntos! Diez días de tareas, y es aleatorio el tiempo que tomará cada una. Queremos saber el tiempo total que dedicaremos a las tareas del hogar. Esto es asumiendo que nos relajamos e ignoramos todo lo que toma más de 15 minutos. O posponga para otro día cualquier cosa que se pueda hacer en menos de 5:

days = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] days.map{|day| day.odd? ? {task: 'dishes', minutes: Random.rand(20)} : {task: 'sweep', minutes: Random.rand(20)}} .select .rejecttask .reduce(0)  sum + task[:minutes]

Mi respuesta es irrelevante porque obtendrá diferentes minutos aleatorios para sus tareas. Si algo de esto es nuevo o confuso, enciende una consola Ruby y dale una vuelta.

PD: Ese ? :negocio .mapse llama ternary. Es solo una declaración if-else. Solo lo estoy usando aquí para ser elegante y tener todo en "una" línea. Debe evitar un ternario tan complicado en su propia base de código.

¡Hasta la próxima!