Combination of Two Arrays in Ruby

Combination of two arrays in Ruby

You can use product to get the cartesian product of the arrays first, then collect the function results.

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

So you can use map or collect to get the results. They are different names for the same method.

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

Generate combinations of values from multiple arrays

If you want all the possible combinations, there's no alternative other than iterating through each of the elements for all arrays.

Creating hashes is not difficult either.

Try this.

a = [1, 2, 3, 4, 5]
b = ['A', 'B', 'C', 'D', 'E']
c = ['J', 'K', 'L', 'M', 'N']
d = ['v', 'w', 'x', 'y', 'z']

result = []

a.each do |a_elem|
b.each do |b_elem|
c.each do |c_elem|
d.each do |d_elem|
result << {a: a_elem, b: b_elem, c: c_elem, d: d_elem}
end
end
end
end

puts "#{result}"

I believe this is what you are looking for.

Ruby Unique combinations of 2 from n arrays of different sizes

Arrays

You can use combination and Cartesian product :

arrays = [[0, 1], [2, 3, 4], [5, 6, 7, 8]]

p arrays.combination(2).flat_map{ |a, b| a.product(b) }.sort
#=> [[0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [0, 5], [0, 6], [0, 7], [0, 8], [1, 5], [1, 6], [1, 7], [1, 8], [2, 5], [2, 6], [2, 7], [2, 8], [3, 5], [3, 6], [3, 7], [3, 8], [4, 5], [4, 6], [4, 7], [4, 8]]

p arrays.combination(2).flat_map{ |a, b| a.product(b) }.sort
#=> [[0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [2, 5], [2, 6], [2, 7], [2, 8], [3, 5], [3, 6], [3, 7], [3, 8], [4, 5], [4, 6], [4, 7], [4, 8]]

p arrays.combination(2).flat_map{|a,b| a.product(b)}.size
#=> 26

Calling combination(2) on the array outputs all the unique pairs of sub-arrays.
For each pair of arrays, every element of the first array is matched with every element of the second array (see Cartesian product).

flat_map is here to avoid getting an array of arrays of arrays.

Size

Using combinations

Your formula is correct for 3 sub-arrays. For n arrays, you need to list all the combinations of two sub-arrays, and sum the product of their respective size :

p arrays.map(&:size).combination(2).map{|s1, s2| s1*s2}.inject(:+)
#=> 26

Alternative

Using the fact that the expanded version of (x+y+z)**2 is

x**2 + 2*xy + y**2 + 2*xz + 2*yz + z**2

we see that :

2*xy + 2*xz + 2*yz = (x+y+z)**2 - (x**2 + y**2 + z**2)

so

xy + xz + yz = ( (x+y+z)**2 - (x**2 + y**2 + z**2) )/2

It doesn't look like much of a shortcut for 3 values, but it generalizes to n arrays, and helps us avoid combination altogether :

sizes = arrays.map(&:size)
p (sizes.inject(:+)**2 - sizes.map{|s| s**2}.inject(:+))/2
#=> 26

Combine array of array into all possible combinations, forward only, in Ruby

Know your Array#product:

a = [['1','2'],['a','b'],['x','y']]
a.first.product(*a[1..-1]).map(&:join)

How to get ALL combinations of array elements in Ruby?

You are looking for permutation instead of combination.

In combinations, we do not care about the order of the elements, and only care about the presence of all the elements in the set.

[1,2,3,4].permutation(3).to_a
#=> [[1, 2, 3], [1, 2, 4], [1, 3, 2], [1, 3, 4], [1, 4, 2], [1, 4, 3], [2, 1, 3], [2, 1, 4], [2, 3, 1], [2, 3, 4], [2, 4, 1], [2, 4, 3], [3, 1, 2], [3, 1, 4], [3, 2, 1], [3, 2, 4], [3, 4, 1], [3, 4, 2], [4, 1, 2], [4, 1, 3], [4, 2, 1], [4, 2, 3], [4, 3, 1], [4, 3, 2]]

Combination of elements from multiple arrays

You should use Array#product here.

phi1 = [0, -36, -72, -108, -144, -180]
psi1 = [-180, -108, -36]
phi2 = [0, -36, -72, -108, -144, -180]
psi2 = [-180, -108, -36]

phi1.product(psi1, phi2, psi2).each do |arr|
puts "angles#{ arr.join("_") }"
arr.each { |angle| puts "select #{angle}" }
end

angles0_-180_0_-180
select 0
select -180
select 0
select -180
angles0_-180_0_-108
select 0
select -180
select 0
select -108
...
angles-180_-36_-180_-108
select -180
select -36
select -180
select -108
angles-180_-36_-180_-36
select -180
select -36
select -180
select -36

phi1.product(psi1, phi2, psi2).count
#=> 324

Ruby's Array Combination Method

Instead of Array#combination, you want Array#permutation:

number = 123
number.to_s.split('').permutation.map(&:join).uniq.sort
# => ["123", "132", "213", "231", "312", "321"]

number = 122
number.to_s.split('').permutation.map(&:join).uniq.sort
# => ["122", "212", "221"]

Combining random elements of multiple arrays

There are a few ways to do this.

1) You can use sample method.

array1.sample #=> return a random element from the array.

Then you can use string interpolation like

result = "#{array1.sample}#{array2.sample}#{array3.sample}" #=> ie "xby"

2) You can generate random index values

array1[rand(array1.length)]

This will generate a random index from 0 to length-1 and call the [] method on the array. You can then use string interpolation as well.

3) You can use the shuffle method then first method

array1.shuffle.first

shuffle will, well, shuffle the array, and you can just return the first element.

I'm just listing the few I can come up with off the top of my head. There are probably tons of other ways to do this.



Related Topics



Leave a reply



Submit