2012-09-30 18 views
5

La diferencia entre Enumerable#each y Enumerable#map es si devuelve el receptor o el resultado del mapa. Volver al receptor es trivial y, por lo general, no es necesario continuar una cadena de métodos después de each como each{...}.another_method (probablemente no he visto ese caso. Incluso si desea volver al receptor, puede hacerlo con tap). Así que creo que todos o la mayoría de los casos en los que se usa Enumerable#each pueden reemplazarse por Enumerable#map. ¿Me equivoco? Si estoy en lo correcto, ¿cuál es el propósito de each? ¿Es map más lento que each?¿No se pueden reemplazar todos o la mayoría de los casos de `cada uno 'por` mapa`?

Editar: sé que no es una práctica común el uso de each cuando no está interesado en el valor de retorno. No estoy interesado en si existe tal práctica, pero estoy interesado en si tal práctica tiene sentido más que desde el punto de vista de la convención.

+1

Usted entiende que 'cada 'es una parte fundamental de Enumerable mientras que' map' no lo es, ¿verdad? ["La clase debe proporcionar un método 'each', que produce miembros sucesivos de la colección."] (Http://ruby-doc.org/core-1.9.3/Enumerable.html). –

+0

@muistooshort No estoy al tanto de eso. Voy a pensar en ello. Gracias. – sawa

+2

Intenta implementar 'map' en términos de' each' y luego 'each' en términos de' map', que pueden darte una idea. –

Respuesta

5

La elección entre map o each debe decidirse por el resultado final deseado: una nueva matriz o ninguna matriz nueva. El resultado de map puede ser enorme y/o tonta:

p ("aaaa".."zzzz").map{|word| puts word} #huge and useless array of nil's 
+0

Si es lento, entiendo que no debería usarlo, pero ¿por qué es tonto? No entiendo eso en absoluto. Ruby heredó de Lisp la idea de que cada evaluación arroja un valor. – sawa

+3

El resultado de este 'mapa' es una matriz con 456976 nil (' puts' devuelve un valor nulo). Se descarta después de haber sido creado. Usar 'each' no lo habría creado en absoluto, salvando la memoria. (Código ligeramente ajustado) – steenslag

+0

Eso es lo que estoy preguntando. Si hace la diferencia en cuanto al rendimiento. – sawa

2

Estoy de acuerdo con lo que ha dicho. Enumerable#each simplemente devuelve el objeto original en el que se invocó, mientras que Enumerable#map establece el elemento actual que se itera sobre el valor de retorno del bloque, y luego devuelve un nuevo objeto con esos cambios.

Dado que Enumerable#each simplemente devuelve el objeto original en sí mismo, puede preferirse muy bien al map cuando se trata de casos en los que simplemente necesita iterar o atravesar elementos.

De hecho, Enumerable#each es una forma simple y universal de hacer un ciclo iterativo tradicional, y cada uno es más preferido que los bucles for en Ruby.

+0

Honestamente, no estoy interesado en cómo otras personas prefieren un método sobre el otro. Me interesa saber si tiene sentido utilizar de manera distinguida cada uno. – sawa

6

La diferencia entre map y each es más importante que si uno devuelve una nueva matriz y el otro no. La diferencia importante radica en cómo comunican su intención.

Cuando usa each, su código dice "estoy haciendo algo para cada elemento". Cuando usa map, su código dice "Estoy creando una nueva matriz transformando cada elemento".

Por lo tanto, aunque podría usar map en lugar de each, a pesar del rendimiento, ahora el código estaría mintiendo acerca de su intención para cualquiera que lo leyera.

0

Puede ver la diferencia significativa entre map y each al componer estos enumaratiors.

Por ejemplo, usted necesita para obtener nueva matriz con indixes en ella:

array.each.with_index.map { |index, element| [index, element] } 

O, por ejemplo, sólo tiene que aplicar algún método para todos los elementos de la matriz y de impresión resultado sin cambiar la matriz original:

m = 2.method(:+) 

[1,2,3].each { |a| puts m.call(a) } #=> prints 3, 4, 5 

Y hay muchos otros ejemplos donde la diferencia entre each y map es clave importante en el código de escritura en el estilo funcional.

Cuestiones relacionadas