Creating permutations from a multi-dimensional array in Ruby
Yup, Array#product
does just that (Cartesian product):
a = [[1,2], [3], [4,5,6]]
head, *rest = a # head = [1,2], rest = [[3], [4,5,6]]
head.product(*rest)
#=> [[1, 3, 4], [1, 3, 5], [1, 3, 6], [2, 3, 4], [2, 3, 5], [2, 3, 6]]
Another variant:
a.inject(&:product).map(&:flatten)
#=> [[1, 3, 4], [1, 3, 5], [1, 3, 6], [2, 3, 4], [2, 3, 5], [2, 3, 6]]
Condensing multidimensional array of permutations into groups
I'm not quite sure if I correctly understand the problem, but given this array:
a = [[1, 12], [1, 5], [1, 6], [5, 12], [6, 12], [12, 5], [12, 6]]
I think you can group the left-hand items by the right-hand items:
h1 = Hash.new { |h, k| h[k] = [] }
a.each { |k, v| h1[v] << k }
h1
#=> {12=>[1, 5, 6], 5=>[1, 12], 6=>[1, 12]}
And apply the same transformation again:
h2 = Hash.new { |h, k| h[k] = [] }
h1.each { |k, v| h2[v] << k }
h2
#=> {[1, 5, 6]=>[12], [1, 12]=>[5, 6]}
This gives:
h2.to_a
#=> [
# [[1, 5, 6], [12]],
# [[1, 12], [5, 6]]
# ]
In recent versions of Ruby you could write it as:
a.group_by(&:last).transform_values { |v| v.map(&:first) }
.group_by(&:last).transform_values { |v| v.map(&:first) }
.to_a
#=> [
# [[1, 5, 6], [12]],
# [[1, 12], [5, 6]]
# ]
The condensed array can be expanded via:
[[[1, 5, 6], [12]], [[1, 12], [5, 6]]].flat_map { |a, b| a.product(b) }
#=> [[1, 12], [5, 12], [6, 12], [1, 5], [1, 6], [12, 5], [12, 6]]
Note that this attempt only works for sub-arrays with two elements, but it should get you started.
Creating combination from a multi-dimensional array in Ruby
first, *rest = [['monday', 'saturday'], ['beginner'], ['kid', 'adult']]
.map{|a| [nil, *a]}
first.product(*rest).map{|a| a.compact.join("-")} - [""]
How to recursively find permutations of two dimensional array in Ruby
The conventional way of solving this problem is to use the methods Array#product and Array#drop.
arr = [[3], [11,2], [11,2,7], [4]]
arr.first.product(*arr.drop(1))
#=> [[3, 11, 11, 4], [3, 11, 2, 4], [3, 11, 7, 4],
# [3, 2, 11, 4], [3, 2, 2, 4], [3, 2, 7, 4]]
If any element of arr
contains duplicates the return value will also contain duplicates. If duplicates are not wanted, use
arr.map(&:uniq).first.product(*arr.drop(1))
The asker has, however, requested a recursive solution. That could be written as follows:
def prod(arr)
return arr if arr.size == 1
t = prod(arr.drop(1))
arr.first.flat_map { |x| t.map { |a| [x] + a } }
end
prod arr
#=> [[3, 11, 11, 4], [3, 11, 2, 4], [3, 11, 7, 4],
# [3, 2, 11, 4], [3, 2, 2, 4], [3, 2, 7, 4]]
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)
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 all possible permutations of an array of arrays (one liner?)
With Array#permutation:
permutations = (1..6).to_a.permutation.map(&:join)
# ["123456", "123465", "123546", ..., "654312", "654321"]
Generate array of limited combinations from another array
You can use Array#permutation
if you don't want repetetions in the subarrays.
col
1 ∈ [1; 3]row
2 ∈ [0; 3]
days.permutation(col).to_a.slice(0, row)
Demonstration
If you want repetitions in the subarrays, you can use Array#repeated_permutation
.
col
∈ [1; 3]row
∈ [0; 33(= 27)]:
days.repeated_permutation(col).to_a.slice(0, row)
Demonstration
If you want repetitions in the subarrays and also expand your column number to the custom, independent from length of the original array number, you can use Array#repeated_combination
.
col
∈ [1; ∞3 )row
∈ [0;col
col
]:
days.repeated_combination(col).to_a.slice(0, row)
Demonstration
1 col
is the number of elements in each subarray.
2 row
is the number of subarrays in the desired 2D array.
3 The upper bound is specified as ∞ to represent that this value is not bounded by the length of the original array.
Creating a combination from arrays and turn it into a multi-dimensional permutations in javascript?
You are looking to get the subsets of length N from your selection of arrays, then create the cartesian product of each subset.
// returns power set of arr filtered by length
function powerset(arr, len, pref=[]) {
if (len == 0) return [pref];
if (len > arr.length) return [];
if (len == arr.length) return [pref.concat(arr)]; // premature optimisation
const next = arr.slice(1);
return powerset(next, len-1, [...pref, arr[0]]).concat(powerset(next, len, pref));
}
// returns cartesian product of the arrays in the argument
function cartesian(arg) {
var r = [], max = arg.length-1;
function helper(arr, i) {
for (var j=0, l=arg[i].length; j<l; j++) {
var a = arr.slice(0); // clone arr
a.push(arg[i][j]);
if (i==max)
r.push(a);
else
helper(a, i+1);
}
}
helper([], 0);
return r;
}
var arrays = [
['a', 'b'],
['c'],
['d', 'e', 'f'],
['x', 'y', 'z']
];
console.log(powerset(arrays, 2).flatMap(cartesian));
console.log(powerset(arrays, 3).flatMap(cartesian));
console.log(powerset(arrays, 4).flatMap(cartesian));
Related Topics
How to Get Indexes of All Occurrences of a Pattern in a String
How to Make Httparty Ignore Ssl
How Is Each_With_Object Supposed to Work
Ruby Backslash to Continue String on a New Line
How to Declare a String with Both Single and Double Quotes in Yaml
Escape Single Quote in Xpath with Nokogiri
How to Match Full Words and Not Substrings in Ruby
Having Trouble Installing Libxml-Ruby on Windows
Replace Words in a String - Ruby
Ruby 1.9 - Invalid Multibyte Char (Us-Ascii)
Complicated Graphviz Tree Structure
Putting the Results of Pp (Or Anything Outputted to Console) into a String
In Ruby Why Does Nil.Id Return 4
Convert (Decode) Hexadecimal String to Binary String
Faulty Ruby Compilation with Rvm: Getting 'Undefined Symbol: Rb_Digest_Md5_Init' While Running Racku