没有产品方法组合阵列

时间:2013-02-02 15:27:29

标签: ruby arrays ruby-1.8

我有两个数组

a = [1,2,3,4]  
b = [a,b,c,d,e,f]

我需要结合创建:

c = [[1,a],[1,b],[1,c],[1,d],[1,e],[1,f],[2,a],[2,b],...]

我会在Ruby 1.9或更高版本中使用product方法,但我运行的是旧版本的Ruby,并且此方法不存在。我不确定如何在不使用c方法的情况下创建product。可以提供任何建议吗?

6 个答案:

答案 0 :(得分:3)

a.map {|ma| b.map { |mb| [ma, mb]} }

答案 1 :(得分:2)

class Array
  def product(other)
    if block_given? then
      each {|el| other.each {|other_el| yield [el, other_el]}}
    else
      res=[]
      each{|el| other.each {|other_el| res << [el, other_el]}}
      res
    end
  end
end

a = [1,2,3,4]  
b = %w(a b c d e f)

p a.product(b) #[[1, "a"], [1, "b"], [1, "c"],...
a.product(b){|e| puts e.join}
#1a
#1b
#1c
#1d...

对于最近的Ruby版本,此代码中的某处会有return to_enum unless block_given?,但旧版Rubies中不提供AFAIK to_enum。真实的product需要多个参数;我还没有找到一种方法来做非递归的。

答案 2 :(得分:1)

c = a.map{|x| b.map{|y| [x,y]}}.flatten(1)

根据您的Ruby版本的年龄,您可能需要使用:

c = a.map{|x| b.map{|y| [x,y]}}.inject([],:concat)

答案 3 :(得分:1)

您正在尝试获取笛卡尔积。

我创建了一个名为CartesianArray的类,它继承自Array并为您提供#product方法。

class CartesianArray < Array

  def initialize(array_one, array_two)
    @array_one, @array_two = array_one, array_two
  end

  def product
    results = []
    @array_one.each do |a1|
      @array_two.each do { |a2| results << [a1, a2] }
    end

    results
  end

end

您可以像这样使用它:

# Test Code
numbers = [1,2,3,4]
letters = ['a','b','c','d','e','f']

cart_array = CartesianArray.new(numbers, letters)
p cart_array.product
[[1, "a"], [1, "b"], [1, "c"], [1, "d"], [1, "e"], [1, "f"], [2, "a"], [2, "b"], [2, "c"], [2, "d"], [2, "e"], [2, "f"], [3, "a"], [3, "b"], [3, "c"], [3, "d"], [3, "e"], [3, "f"], [4, "a"], [4, "b"], [4, "c"], [4, "d"], [4, "e"], [4, "f"]]

如果您不喜欢将其保留在该课程中,那么我非常确定您可以提取#product方法并修改它以适合您的代码。

答案 4 :(得分:0)

当然,有比这更简单,更有效的方法 -

(a+b).combination(2).map {|c| c if a.include?(c.join.to_i)}.compact

但我喜欢用Ruby写的不同可能的一个衬垫。

答案 5 :(得分:0)

Backports gem

在旧版Rubies中获取Array#product的最简单方法是使用backports gem。它添加了此方法to Ruby 1.87Ruby 1.9.2