0

I have a Array multidimensionnel like:

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

How to get a combinaison each element except the combinaison in the same array: [1, 1],[1, 4],[2, 3]

I want to get:

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

Thanks.

Pf Dong
  • 21
  • 3

2 Answers2

3

Short answer is:

[[1, 1, 4], [2],[2, 3]].combination(2).flat_map {|x,y| x.product(y)}.uniq
# => [[1, 2], [4, 2], [1, 3], [4, 3], [2, 2], [2, 3]]

Step by step

  1. step1 = [[1, 1, 4], [2],[2, 3]].combination(2) 
    # => [[[1, 1, 4], [2]], [[1, 1, 4], [2, 3]], [[2], [2, 3]]]
    
  2. step2 = step1.flat_map {|x,y| x.product(y)}
    # => [[1, 2], [1, 2], [4, 2], [1, 2], [1, 3], [1, 2], [1, 3], [4, 2], [4, 3], [2, 2], [2, 3]]
    
  3. result = step2.uniq
    # => [[1, 2], [4, 2], [1, 3], [4, 3], [2, 2], [2, 3]]
    

Update

For full uniqueness you could use:

[[1, 1, 4], [2],[2, 3, 4]].combination(2).flat_map {|x,y| x.product(y)}.map(&:sort).uniq
nsave
  • 984
  • 9
  • 27
  • if i have : [[1, 1, 4], [2],[2, 3, 4]].combination(2).map {|x,y| x.product(y)}.flatten(1).sort.uniq, i get [[1, 2], [1, 3], [1, 4], [2, 2], [2, 3], [2, 4], [4, 2], [4, 3], [4, 4]], so [2, 4] and [4, 2] is not uniq – Pf Dong Oct 23 '15 at 12:51
  • Check my update. Next time please describe what you want with all details – nsave Oct 23 '15 at 13:31
  • Thanks, I get it too. – Pf Dong Oct 23 '15 at 13:50
1
arr = [[1, 1, 4], [2], [2, 3]]

a = arr.map(&:uniq)
(arr.size-1).times.flat_map { |i| arr[i].product(arr[i+1..-1].flatten.uniq)}.uniq
  #=> [[1,2],[1,3],[4,2],[4,3],[2,2],[2,3]]

Here's another way that uses the method Array#difference that I defined here:

arr.flatten.combination(2).to_a.difference(arr.flat_map { |a| a.combination(2).to_a }).uniq

Array#difference is similar to Array#-. The difference is illustrated in the following example:

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

a     -      b #=> [1]
a.difference b #=> [1, 3, 2, 2]
Community
  • 1
  • 1
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100