web-dev-qa-db-fra.com

ce qui est différent entre chacun et la méthode de collecte en Ruby

De ce code, je ne connais pas la différence entre les deux méthodes, collect et 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
60
mko

Array#each prend un tableau et applique le bloc donné à tous les éléments. Cela n'affecte pas le tableau ou crée un nouvel objet. C'est juste une façon de faire une boucle sur les objets. En outre, cela revient à soi.

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

Imprime 2,4,6,8 et retourne [1,2,3,4] quoi qu'il arrive

Array#collect est identique à Array#map et applique le bloc de code donné à tous les éléments et renvoie le nouveau tableau. Il suffit de mettre 'Projette chaque élément d’une séquence dans une nouvelle forme'

  arr.collect {|x| x*2}

Retours [2,4,6,8]

Et dans votre code

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

a est un tableau mais il s’agit en fait d’un tableau de Nil \ [nil, nil, nil] car puts x.succ renvoie nil (même s’il affiche M AA K).

Et 

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

est également un tableau. Mais sa valeur est ["L", "Z", "J"], car il revient à soi.

104
RameshVel

Array#each prend juste chaque élément et le met dans le bloc, puis retourne le tableau d'origine. Array#collect prend chaque élément et le place dans un nouveau tableau qui est renvoyé:

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

each est pour quand vous voulez itérer sur un tableau et faire ce que vous voulez dans chaque itération. Dans la plupart des langages (impératifs), il s'agit du marteau «taille unique» que les programmeurs recherchent lorsque vous devez traiter une liste.

Pour les langages plus fonctionnels, vous ne faites ce type d'itération générique que si vous ne pouvez le faire autrement. La plupart du temps, la carte ou la réduction sera plus appropriée (collecter et injecter en Ruby)

collect est pour quand vous voulez transformer un tableau en un autre tableau 

inject est pour quand vous voulez transformer un tableau en une valeur unique 

5
Matt Briggs

Voici les deux extraits de code source, selon le 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() renvoie la valeur renvoyée par le bloc ( voir aussi cet article de blog sur la métaprogrammation ). 

Donc each ne fait que rendements et renvoie le tableau d'origine, alors que collect crée un nouveau tableau et y insère les résultats du bloc; alors il retourne ce nouveau tableau. 

Extraits de code source: each , collect

2
miku

La différence est ce qu'il revient. Dans votre exemple ci-dessus a == [nil,nil,nil] (la valeur de met x.succ) tandis que b == ["L", "Z", "J"] (le tableau d'origine)

À partir de Ruby-doc, collect effectue les opérations suivantes:

Invoque le bloc une fois pour chaque élément de soi. Crée un nouveau tableau contenant les valeurs renvoyées par le bloc.

Chacun retourne toujours le tableau d'origine. Logique?

1
hb922

Je pense qu'un moyen plus facile de comprendre ce serait comme ci-dessous:

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

Au lieu de cela, si vous utilisez collect:

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

De plus, vous pouvez utiliser .collect! pour muter le tableau d'origine.

0
Edmund Lee

Chacune est une méthode définie par toutes les classes incluant le module Enumerable. Object.eachretourne un objet Enumerable::Enumerator. C'est ce que d'autres méthodes Enumerable utilisent pour parcourir l'objet. Les méthodes each de chaque classe se comportent différemment. 

Dans la classe Array, lorsqu'un bloc est passé à each, il exécute des instructions du bloc sur chaque élément, mais renvoie finalement self. Ceci est utile lorsque vous n'avez pas besoin d'un tableau, mais vous souhaitez peut-être simplement tableau et utiliser le comme arguments à d’autres méthodes. inspect et map retournent un nouveau tableau avec les valeurs renvoyées d'exécution du bloc sur chaque élément. Vous pouvez utiliser map! et collect! pour effectuer des opérations sur le tableau d'origine.

0
serengeti12