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
How to Sort an Array of Hashes by a Value in the Hash
Warning: Can't Verify Csrf Token Authenticity in Case of API Development
Can Someone Explain the Class.Superclass.Class.Superclass Paradox
How to Check If a Given Directory Exists in Ruby
Differencebetween Send_Data and Send_File in Ruby on Rails
How to Have Multiple Versions of Ruby and Rails, and Their Combinations on Windows
Problems Installing Ruby on Mountain Lion - Ruby 1.9.3 Wont' Compile
Spinning Background Tasks in Rails
Ruby on Rails: Can You Put Ruby Code in a Yaml Config File
Differencebetween Class and Klass in Ruby
Digital Signature Verification with Openssl
Add Method to an Instanced Object
Using Implicit 'Subject' with 'Expect' in Rspec-2.11
Rails: Unpermitted Parameter in Rails 5