为什么each_cons会产生数组而不是多个值?

时间:2016-06-07 07:29:12

标签: arrays ruby enumerator

我只是想对数组中的连续元素应用二元运算,例如:

[1, 2, 3, 4].each_cons(2).map { |a, b| a.quo(b) }
#=> [(1/2), (2/3), (3/4)]

这是一个人为的例子,操作并不重要。

我很惊讶,我不能写:

[1, 2, 3, 4].each_cons(2).map(&:quo)
#=> NoMethodError: undefined method `quo' for [1, 2]:Array

这是因为each_cons不会产生多个值,而是包含值的数组。

它的工作原理如下:

def each_cons_arrays
  return enum_for(__method__) unless block_given?
  yield [1, 2]
  yield [2, 3]
  yield [3, 4]
end

each_cons_arrays.map(&:quo)
#=> NoMethodError: undefined method `quo' for [1, 2]:Array

我希望:

def each_cons_values
  return enum_for(__method__) unless block_given?
  yield 1, 2
  yield 2, 3
  yield 3, 4
end

each_cons_values.map(&:quo)
#=> [(1/2), (2/3), (3/4)]

这背后的理由是什么?为什么总是有一个数组更好?

顺便说一下,with_index确实产生了多个值:

[1, 1, 1].each.with_index(2).map(&:quo)
#=> [(1/2), (1/3), (1/4)]

1 个答案:

答案 0 :(得分:0)

根据我的经验,将ruby中的多个值视为数组会有所帮助。

它将其视为

[1,2,3].each_cons(2) do |iter|
  a,b = iter
  do_stuff(a,b)
end

如果您想这样做,我会将quo方法添加到自定义类中,然后执行

class Foobar
  def initialize(a,b)
    @a = a
    @b = b
  end

  def quo
    do_stuff
  end
end

[1,2,3]
  .each_cons(2)
  .map { |a,b| Foobar.new(a,b) }
  .map(:quo)

这对您的用例有用吗?