Ruby中的每个方法和收集方法有啥不同[重复]

Posted

技术标签:

【中文标题】Ruby中的每个方法和收集方法有啥不同[重复]【英文标题】:what's different between each and collect method in Ruby [duplicate]Ruby中的每个方法和收集方法有什么不同[重复] 【发布时间】:2011-07-17 21:42:28 【问题描述】:

从这段代码我不知道collecteach这两种方法的区别。

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

【问题讨论】:

你为什么要printing a.class, b.class?改为打印ab,就清楚了。请参阅重构的答案。我认为你混淆了你的两个单行的效果,它们是相同的,它们的返回值是不同的。 当您想查看对象的内容时,使用p 而不是print。我忘了提那个。在上面的代码中尝试p ap b 【参考方案1】:

Array#each 接受一个数组并将给定的块应用于所有项目。它不会影响数组或创建新对象。这只是循环项目的一种方式。它也返回自我。

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

打印 2,4,6,8 并返回 [1,2,3,4] 无论如何

Array#collectArray#map 相同,它将给定的代码块应用于所有项目并返回新数组。简单地把'将序列的每个元素投影到一个新的形式'

  arr.collect |x| x*2

返回 [2,4,6,8]

在你的代码中

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

a 是一个数组,但它实际上是一个 Nil 的 [nil,nil,nil] 数组,因为 puts x.succ 返回 nil(即使它打印 M AA K)。

还有

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

也是一个数组。但是它的值是["L","Z","J"],因为它返回self。

【讨论】:

【参考方案2】:

Array#each 只是将每个元素放入块中,然后返回原始数组。 Array#collect 获取每个元素并将其放入一个新数组中并返回:

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

【讨论】:

【参考方案3】:

each 用于当你想迭代一个数组,并在每次迭代中做任何你想做的事情。在大多数(命令式)语言中,这是程序员在需要处理列表时使用的“一刀切”的锤子。

对于更多的函数式语言,如果您不能以任何其他方式进行,则只能进行这种通用迭代。大多数时候,map 或 reduce 会更合适(在 ruby​​ 中收集和注入)

collect 用于将一个数组转换为另一个数组时

inject 用于将数组转换为单个值时

【讨论】:

【参考方案4】:

这里有两个源代码sn-ps,根据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() 返回块返回的值 (see also this blog post on metaprogramming)。

所以each 只是yields 并返回原始数组,而collect 创建一个新数组并将块的结果推入其中;然后它返回这个新数组。

来源sn-ps:each,collect

【讨论】:

【参考方案5】:

不同之处在于它返回的内容。在你上面的例子中 a == [nil,nil,nil](puts x.succ 的值)而b == ["L", "Z", "J"](原始数组)

从 ruby​​-doc 中,collect 执行以下操作:

为每个元素调用一次块 自己。创建一个新数组,包含 块返回的值。

每个总是返回原始数组。有意义吗?

【讨论】:

【参考方案6】:

Each 是由包含 Enumerable 模块的所有类定义的方法。 Object.each返回一个 Enumerable::Enumerator 对象。这是其他 Enumerable 方法用来遍历对象的方法。 each 每个类的方法行为不同。

在Array类中,当一个block传递给each时,它会在每个元素上执行block的语句,但最终返回self。这在你不需要数组时很有用,但你可能只是想要从数组中选择元素并将其用作其他方法的参数。 inspectmap 返回一个新数组,其中包含在每个元素上执行块的返回值。您可以使用map!collect! 对原始数组进行操作。

【讨论】:

【参考方案7】:

我认为更容易理解它的方法如下:

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

相反,如果您使用收集:

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

另外,您可以使用.collect! 来改变原始数组。

【讨论】:

以上是关于Ruby中的每个方法和收集方法有啥不同[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 中的方法和消息有啥区别? [关闭]

不同的字符串比较方法有啥区别[重复]

Ruby:比较级之间有啥区别:“||”和“或” [重复]

ruby - uniq 有啥区别!和 uniq [重复]

C#中的方法与属性-有啥区别[重复]

Django rest-auth中的create和perform_create方法有啥区别[重复]