每个对象的累加器不断重新初始化

时间:2019-02-21 00:29:08

标签: ruby accumulate

我正在尝试写一个广义的笛卡尔积,其中[n1,n2,... ni]的输入数据产生的输出数据是所有mj的[m1,m2,... mi]的数组0 <= mj

#!/usr/bin/ruby

def gcp(dims)
  first = dims.shift
  dims.each_with_object((0...first).to_a) do |dim, v|
    puts "\nv: #{v}, dim: #{dim}"
    p v.product((0...dim).to_a)
  end
end

gcp([3,2,4])

这将产生以下输出:

v: [0, 1, 2], dim: 2
[[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]

v: [0, 1, 2], dim: 4
[[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]

p方法是直通的,因此该块的返回值在第一次迭代时应为[[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]],而在第二次迭代时应为v的值,除非我严重误解了each_with_object

2 个答案:

答案 0 :(得分:1)

我承认我还没有完全理解这个问题,但是我已经解决了一个类似的问题,该问题可以解释为什么您的代码未更新v

让我们逐步执行代码,返回所需结果而不是一路显示。

dims = [3,2,4]

first = dims.shift
  #=> 3 
dims
  #=> [2, 4]     dims

表达式

dims.each_with_object((0...first).to_a) do |dim, v|
  v.product((0...dim).to_a)
end

实际上与

相同
v = []
dims.each do |dim|
  v.product((0...dim).to_a)
end
v #=> []

v仍然是一个空数组,这并不奇怪,因为v的值在循环中没有改变。 v.product((0...dim).to_a)的返回值被发射到太空中,再也不会被看到。您需要在循环中分配任务。

现在考虑以下内容。

dims = [3,2,4]

v = []
dims.each do |n|
  v << (0...n).to_a
end
v #=> [[0, 1, 2], [0, 1], [0, 1, 2, 3]] 

(或v.push((0..n).to_a))。要使用Enumerable#each_with_object,我们将通过删除第一(v = [])和最后(v)条语句,将each更改为each_with_object([])(该参数作为该对象的初始值,该方法将返回),并添加一个包含该对象的块变量v

dims.each_with_object([]) do |n,v|
  v << (0...n).to_a
end
  #=> [[0, 1, 2], [0, 1], [0, 1, 2, 3]] 

我们可以使用Emumerable#map简化此操作:

dims.map do |n|
  (0...n).to_a
end
  #=> [[0, 1, 2], [0, 1], [0, 1, 2, 3]] 

根据您的需求,您可能更喜欢使用Emumerable#flat_map

dims.flat_map do |n|
  (0...n).to_a
end
  #=> [0, 1, 2, 0, 1, 0, 1, 2, 3]

答案 1 :(得分:1)

每次迭代都获得相同的对象,因此您需要在块内对对​​象进行突变,或者使用reduce

def gcp(dims)
  first = dims.shift
  dims.reduce((0...first).to_a) do |v, dim|
    puts "\nv: #{v}, dim: #{dim}"
    p v.product((0...dim).to_a)
  end
end

gcp([3,2,4])

结果:

v: [0, 1, 2], dim: 2
[[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]

v: [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]], dim: 4
[[[0, 0], 0], [[0, 0], 1], [[0, 0], 2], [[0, 0], 3], [[0, 1], 0], [[0, 1], 1], [[0, 1], 2], [[0, 1], 3], [[1, 0], 0], [[1, 0], 1], [[1, 0], 2], [[1, 0], 3], [[1, 1], 0], [[1, 1], 1], [[1, 1], 2], [[1, 1], 3], [[2, 0], 0], [[2, 0], 1], [[2, 0], 2], [[2, 0], 3], [[2, 1], 0], [[2, 1], 1], [[2, 1], 2], [[2, 1], 3]]