Ruby和Ruby中的方法有什么不同?
从这个代码我不知道两个方法之间的区别, collect
和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
Array#each
一个数组,并将给定的块应用于所有项目。 它不影响数组或创build一个新的对象。 这只是一个循环的项目的方式。 它也回报自我。
arr=[1,2,3,4] arr.each {|x| puts x*2}
打印2,4,6,8,无论如何返回[1,2,3,4]
Array#collect
与Array#map
相同,它将所有项目的给定代码块应用并返回新数组。 简单地把“将一个序列的每个元素投射到一个新的forms”
arr.collect {|x| x*2}
退货[2,4,6,8]
并在您的代码
a = ["L","Z","J"].collect{|x| puts x.succ} #=> M AA K
a是一个数组,但它实际上是一个puts x.succ
的[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”],因为它返回自我。
Array#each
只取每个元素并将其放入块中,然后返回原始数组。 Array#collect
将每个元素都放到一个新的数组中,并返回:
[1, 2, 3].each { |x| x + 1 } #=> [1, 2, 3] [1, 2, 3].collect { |x| x + 1 } #=> [2, 3, 4]
each
用于当你想迭代一个数组,并在每次迭代中做任何你想要的。 在大多数(必要的)语言中,当程序员需要处理列表时,这就是“一刀切”的锤子。
对于更多的函数式语言,如果您不能以其他方式进行,只能进行这种types的generics迭代。 大多数时候,无论是地图还是缩小都会更合适(收集并注入ruby)
collect
是为了当你想把一个数组转换成另一个数组
inject
是为了当你想把一个数组转换成一个单一的值
这里是两个源代码片断,根据文档 …
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
产生并返回原始数组,而collect
创build一个新的数组,并推动块的结果, 那么它返回这个新的数组。
源代码片段: 每个 收集
不同的是它返回。 在上面a == [nil,nil,nil]
例子中, a == [nil,nil,nil]
b == ["L", "Z", "J"]
(原始数组)时a == [nil,nil,nil]
(puts x.succ的值)
从ruby文档收集做以下几点:
为每个自我元素调用一次块。 创build一个包含块返回值的新数组。
每个总是返回原始数组。 说得通?
每个类都是由所有包含Enumerable模块的类定义的方法。 Object.each
返回一个Enumerable::Enumerator
对象。 这是其他Enumerable方法用来迭代对象的内容。 each
类的each
方法的行为不同。
在Array类中,当一个块被传递给each
元素时,它会在每个元素上执行块的语句,但是最后返回self。当你不需要数组时,这是很有用的,但是你可能只想从数组并将其用作其他方法的参数。 inspect
并map
返回一个新的数组,每个元素的块的执行返回值。 你可以用map!
并collect!
在原始数组上执行操作。
我认为一个更容易理解的方法如下:
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!
来改变原始数组。