programacion objetos metodos manejo lista instanciar herencia ejemplos ejemplo clases clase ruby each collect

objetos - lo que es diferente entre cada método y recoger en Ruby



manejo de objetos en ruby (7)

Esta pregunta ya tiene una respuesta aquí:

De este código no sé la diferencia entre los dos métodos, collect y each .

a = ["L","Z","J"].collect{|x| puts x.succ} #=> M AA K print a.class #=> Array b = ["L","Z","J"].each{|x| puts x.succ} #=> M AA K print b.class #=> Array


Aquí están los dos fragmentos de código fuente, de acuerdo con los docs ...

VALUE rb_ary_each(VALUE ary) { long i; RETURN_ENUMERATOR(ary, 0, 0); for (i=0; i<RARRAY_LEN(ary); i++) { rb_yield(RARRAY_PTR(ary)[i]); } return ary; } # .... .... .... .... .... .... .... .... .... .... .... .... static VALUE rb_ary_collect(VALUE ary) { long i; VALUE collect; RETURN_ENUMERATOR(ary, 0, 0); collect = rb_ary_new2(RARRAY_LEN(ary)); for (i = 0; i < RARRAY_LEN(ary); i++) { rb_ary_push(collect, rb_yield(RARRAY_PTR(ary)[i])); } return collect; }

rb_yield() devuelve el valor devuelto por el bloque ( consulte también esta publicación de blog en metaprogramación ).

Así que each solo cede y devuelve la matriz original, mientras que la collect crea una nueva matriz y empuja los resultados del bloque hacia ella; luego devuelve esta nueva matriz.

Fragmentos de fuente: each , collect


Cada uno es un método definido por todas las clases que incluyen el módulo Enumerable. Object.each devuelve un objeto Enumerable::Enumerator . Esto es lo que otros métodos Enumerable usan para iterar a través del objeto. each método de cada clase se comporta de manera diferente.

En la clase Array, cuando se pasa un bloque a each , realiza declaraciones del bloque en cada elemento, pero al final se devuelve self. Esto es útil cuando no se necesita una matriz, pero tal vez solo se desee elegir elementos del bloque. matriz y utilizar los argumentos como a otros métodos. inspect y map devuelve una nueva matriz con valores de retorno de la ejecución del bloque en cada elemento. Puedes usar el map! y collect! para realizar operaciones en la matriz original.


Creo que una forma más fácil de entenderlo sería la siguiente:

nums = [1, 1, 2, 3, 5] square = nums.each { |num| num ** 2 } # => [1, 1, 2, 3, 5]

En cambio, si usas collect:

square = nums.collect { |num| num ** 2 } # => [1, 1, 4, 9, 25]

Y además, puedes usar .collect! para mutar la matriz original.


La diferencia es lo que devuelve. En su ejemplo anterior a == [nil,nil,nil] (el valor de puts x.succ) while b == ["L", "Z", "J"] (la matriz original)

Del ruby-doc, collect hace lo siguiente:

Invoca bloque una vez para cada elemento de uno mismo. Crea una nueva matriz que contiene los valores devueltos por el bloque.

Cada uno siempre devuelve el conjunto original. ¿Tiene sentido?


Array#each simplemente toma cada elemento y lo coloca en el bloque, luego devuelve el conjunto original. Array#collect toma cada elemento y lo coloca en una nueva matriz que se devuelve:

[1, 2, 3].each { |x| x + 1 } #=> [1, 2, 3] [1, 2, 3].collect { |x| x + 1 } #=> [2, 3, 4]


Array#each toma una matriz y aplica el bloque dado sobre todos los elementos. No afecta la matriz o crea un nuevo objeto. Es solo una forma de pasar por encima de los elementos. También regresa a sí mismo.

arr=[1,2,3,4] arr.each {|x| puts x*2}

Imprime 2,4,6,8 y devuelve [1,2,3,4] pase lo que pase

Array#collect es igual que Array#map y aplica el bloque de código dado en todos los elementos y devuelve la nueva matriz. simplemente ponga ''Proyecta cada elemento de una secuencia en una nueva forma''

arr.collect {|x| x*2}

Devuelve [2,4,6,8]

Y en tu código

a = ["L","Z","J"].collect{|x| puts x.succ} #=> M AA K

a es una matriz pero en realidad es una matriz de Nil [nil, nil, nil] porque puts x.succ devuelve nil (aunque imprima M AA K).

Y

b = ["L","Z","J"].each{|x| puts x.succ} #=> M AA K

también es una matriz. Pero su valor es ["L", "Z", "J"], porque regresa a sí mismo.


each es para cuando quieras iterar sobre una matriz y hacer lo que quieras en cada iteración. En la mayoría de los idiomas (imperativos), este es el martillo de "talla única" al que los programadores recurren cuando necesita procesar una lista.

Para lenguajes más funcionales, solo realiza este tipo de iteración genérica si no puede hacerlo de otra manera. La mayoría de las veces, ya sea mapa o reducir será más apropiado (recoger e inyectar en rubí)

collect es para cuando quieres convertir una matriz en otra matriz

inject es para cuando quieres convertir una matriz en un solo valor