user1261284
user1261284

Reputation: 191

Getting combinations of multilevel arrays in ruby

a = [1,2,3,4].combination(3).to_a

returns

[[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

What do I need to do to get the following combination of the array shown below

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

should be

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

It is important that values from the second level aren't put in a combination together.

The array could also be

[["1a","1b","1c",...],2,3,4]

The values themselves are unique.

Thanks in advance!

Upvotes: 1

Views: 80

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

The solution below will flatten and product any combination of arrays and scalars:

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

a.combination(a.size - 1).map do |e| 
  e.map { |scalar| [*scalar] } # convert scalars to arrays of size 1
end.map do |arrays| 
  arrays.reduce &:product      # reduce by vector/cartesian product
end.flat_map do |deeps| 
  deeps.map &:flatten          # flatten the result
end

#⇒ [
#      ["1a", 2, 3], ["1b", 2, 3], ["1a", 2, "4a"], ["1a", 2, "4b"],
#      ["1b", 2, "4a"], ["1b", 2, "4b"], ["1a", 3, "4a"], 
#      ["1a", 3, "4b"], ["1b", 3, "4a"], ["1b", 3, "4b"],
#      [2, 3, "4a"], [2, 3, "4b"]
#  ]

Hope it helps.

Upvotes: 3

user12341234
user12341234

Reputation: 7213

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

head, tail = [a[0], a[1..-1]]

res = head.flat_map{|h| ([h] + tail).combination(3).to_a}.uniq

Upvotes: 2

Related Questions