如何简化此枚举器代码?

时间:2014-05-07 13:11:18

标签: ruby optimization enumerator simplification

我希望优化以下代码以简洁。

x1.each { |x| 
  x2.each { |y|
    ....
    xN.each { |z|
      yield {}.merge(x).merge(y)...... merge(z)
    }
  }
}

假设x1, x2, ..., xNEnumerator个对象。

  1. 以上不简洁
  2. 它适用于x1,x2作为Array s,但不适用于Enumerator s
    • 因为应该为内部循环重置枚举器迭代器
  3. 我试过这个但没有成功:

    [x1, x2, ..., xN].reduce(:product).map { |x| x.reduce :merge }
    

    有什么建议吗?

    更新

    目前解决了:

    [x1, x2, ..., xN].map(:to_a).reduce(:product).map { |x| 
      yield x.flatten.reduce(:merge) 
    }
    

1 个答案:

答案 0 :(得分:5)

我将从第2点开始:

  • 至少在Enumerators我已经测试过([{a: 1}, {a: 2}, {a: 3}].each)你的代码工作了 - 显然Enumerator#each要么在最后倒带,要么使用自己的指针。
  • 要做你想做的事,你需要在Enumerator个对象(特别是内部对象)上进行多次迭代,首先在每个对象上调用to_a不会增加你的时间复杂度(它将保持O(n1*n2*...*nk)

对于#1点,如果调用to_a是不可能的,你可以考虑递归:

def deep_merge(enum = nil, *enums)
  if enum.nil?
    yield({})
  else
    enum.each do |x|
      deep_merge(*enums) do |h|
        yield h.merge(x)
      end
    end
  end
end

现在你可以致电deep_merge(x1, x2, ... xN)并获得所需的结果......