Ruby 中的each 和collect 方法有什么不同

发布于 2024-10-22 18:49:27 字数 266 浏览 8 评论 0原文

从这段代码中我不知道 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

From this code I don't know the difference between the two methods, collect and 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

你的笑 2024-10-29 18:49:27

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

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

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

Array#collect 与 Array#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 AAK)。

并且

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

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

Array#each takes an array and applies the given block over all items. It doesn't affect the array or creates a new object. It is just a way of looping over items. Also it returns self.

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

Prints 2,4,6,8 and returns [1,2,3,4] no matter what

Array#collect is same as Array#map and it applies the given block of code on all the items and returns the new array. simply put 'Projects each element of a sequence into a new form'

  arr.collect {|x| x*2}

Returns [2,4,6,8]

And In your code

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

a is an Array but it is actually an array of Nil's [nil,nil,nil] because puts x.succ returns nil (even though it prints M AA K).

And

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

also is an Array. But its value is ["L","Z","J"], because it returns self.

玩世 2024-10-29 18:49:27

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

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

Array#each just takes each element and puts it into the block, then returns the original array. Array#collect takes each element and puts it into a new array that gets returned:

[1, 2, 3].each { |x| x + 1 }    #=> [1, 2, 3]
[1, 2, 3].collect { |x| x + 1 } #=> [2, 3, 4]
醉南桥 2024-10-29 18:49:27

each 适用于当您想要迭代数组并在每次迭代中执行您想要的操作时。在大多数(命令式)语言中,这是程序员在需要处理列表时使用的“一刀切”锤子。

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

collect适用于当你想将一个数组转换为另一个数组时

inject适用于当你想将数组转换为单个值时

each is for when you want to iterate over an array, and do whatever you want in each iteration. In most (imperative) languages, this is the "one size fits all" hammer that programmers reach for when you need to process a list.

For more functional languages, you only do this sort of generic iteration if you can't do it any other way. Most of the time, either map or reduce will be more appropriate (collect and inject in ruby)

collect is for when you want to turn one array into another array

inject is for when you want to turn an array into a single value

等待圉鍢 2024-10-29 18:49:27

根据 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() 返回块返回的值 (另请参阅这篇关于元编程的博客文章)。

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

源代码片段:每个收集

Here are the two source code snippets, according to the 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() returns the value returned by the block (see also this blog post on metaprogramming).

So each just yields and returns the original array, while collect creates a new array and pushes the results of the block into it; then it returns this new array.

Source snippets: each, collect

不喜欢何必死缠烂打 2024-10-29 18:49:27

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

根据 ruby​​-doc,collect 执行以下操作:

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

每个总是返回原始数组。有道理吗?

The difference is what it returns. In your example above
a == [nil,nil,nil] (the value of puts x.succ) while b == ["L", "Z", "J"] (the original array)

From the ruby-doc, collect does the following:

Invokes block once for each element of
self. Creates a new array containing
the values returned by the block.

Each always returns the original array. Makes sense?

相权↑美人 2024-10-29 18:49:27

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

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

Each is a method defined by all classes that include the Enumerable module. Object.eachreturns a Enumerable::Enumerator Object. This is what other Enumerable methods use to iterate through the object. each methods of each class behaves differently.

In Array class when a block is passed to each, it performs statements of the block on each element, but in the end returns self.This is useful when you don't need an array, but you maybe just want to choose elements from the array and use the as arguments to other methods. inspect and map return a new array with return values of execution of the block on each element. You can use map! and collect! to perform operations on the original array.

注定孤独终老 2024-10-29 18:49:27

我认为更简单的理解方法如下:

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

相反,如果您使用collect:

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

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

I think an easier way to understand it would be as below:

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

Instead, if you use collect:

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

And plus, you can use .collect! to mutate the original array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文