【问题标题】:Combination of two arrays in RubyRuby中两个数组的组合
【发布时间】:2010-12-05 08:13:59
【问题描述】:

Ruby 实现追随的方式是什么?

a = [1,2]
b = [3,4]

我想要一个数组:

=> [f(1,3) ,f(1,4) , f(2,3) ,f(2,4)]

【问题讨论】:

  • @lucasarruda 这与 OP 的要求不太一样。 Zip 将创建[a[0], b[0]][a[1], b[1]] 的数组。它不包括[a[0], b[1]]a.zip(b) => [[1,3],[2,4]]
  • 谢谢@KNejad,你是对的。删除了我的评论。

标签: ruby combinations


【解决方案1】:

您可以使用product先获取数组的笛卡尔积,然后收集函数结果。

a.product(b) => [[1, 3], [1, 4], [2, 3], [2, 4]]

因此您可以使用mapcollect 来获取结果。它们是同一方法的不同名称。

a.product(b).collect { |x, y| f(x, y) }

【讨论】:

  • 产品仅从 1.9 开始内置。
  • 产品在 1.8.7 中 - 我用它来做 Pierr 要求的事情
  • @FloatingRock 不正确,它是组合而不是排列。见ruby-doc.org/core-2.1.3/Array.html#method-i-product
  • @FloatingRock 不是这样。每个项目的第一个元素总是来自第一个列表,第二个元素来自第二个列表,依此类推。这是元素的所有可能组合,但它们永远不会重新排序,所以它不是排列。
  • 对于三个数组 a.product(b,c) 等等(直到内存不足)。 Ruby 太酷了!
【解决方案2】:
a.map {|x| b.map {|y| f(x,y) } }.flatten

注意:在 1.8.7+ 上,您可以添加 1 作为 flatten 的参数,因此当 f 返回一个数组时,您仍然会得到正确的结果。

这是任意数量数组的抽象:

def combine_arrays(*arrays)
  if arrays.empty?
    yield
  else
    first, *rest = arrays
    first.map do |x|
      combine_arrays(*rest) {|*args| yield x, *args }
    end.flatten
      #.flatten(1)
  end
end

combine_arrays([1,2,3],[3,4,5],[6,7,8]) do |x,y,z| x+y+z end
# => [10, 11, 12, 11, 12, 13, 12, 13, 14, 11, 12, 13, 12, 13, 14, 13, 14, 15, 12, 13, 14, 13, 14, 15, 14, 15, 16]

【讨论】:

  • 虽然我不确定这是否是最好的方法,但它会起作用(虽然想不出更好的方法,所以 +1)
  • 我希望我可以为任意数量的数组组合 +2。很酷!
  • 我也提出了这个.. 但后来我知道应该有更简单的方法来做到这一点... +1 但@Aaron Hinni 回答它更干净
【解决方案3】:

Facets 有Array#product,它会给你数组的叉积。对于两个数组的情况,它也被称为** operator。使用它,它看起来像这样:

require 'facets/array'
a = [1,2]
b = [3,4]

(a.product b).collect {|x, y| f(x, y)}

如果您使用的是 Ruby 1.9,product 是一个内置的数组函数。

【讨论】:

  • 为什么人们总是说 Array#product 是 1.9 主义?至少在 1.8.7 中。
猜你喜欢
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多