How to get all combinations from multiple arrays?
How many combinations are there?
So first the question how many combinations are there? And the answer is you have to multiply the amount of every array with each other.
So (c = amount1):
carray 1 * carray 2 * ... * carray n
And specific for your example:
carray 1 * carray 2 * carray 3 = 2 * 2 * 2 = 8
*1 And if you wonder why I chose c for amount, because of the function count() in php
Getting all combinations together
How do we get now all combinations with the amount of arrays, which we have?
We loop through all our combinations, which we already have(Starting off with one combination, an "empty combination" ($combinations = [[]];
)), and for each combination we go through our next data array and combine each combination with each input data to a new combination.
Now we do this until we get the desired length for each combination.
So as an example:
Array with the elements (Empty array is '[]'):
[
[1, 2],
[3, 4]
]
//↓ new combinations for the next iteration
│
array NAN*:
Combinations:
- [] │ -> []
│
array 1 [1,2]: ┌─────────────┤
│ │
Combinations: v v
- [] + 1 │ -> [1]
- [] + 2 │ -> [2]
│
array 2 [3,4]: ┌─────────────┤
│ │
Combinations: v v
- [] + 3 │ -> [3]
- [] + 4 │ -> [4]
- [1] + 3 │ -> [1,3] //desired length 2 as we have 2 arrays
- [1] + 4 │ -> [1,4] //desired length 2 as we have 2 arrays
- [2] + 3 │ -> [2,3] //desired length 2 as we have 2 arrays
- [2] + 4 │ -> [2,4] //desired length 2 as we have 2 arrays
//↑ All combinations here
* NAN: not a number
So as you can see in the above example we now have all combinations with the length of the amount of all arrays which we have.
But to get only the combinations with the desired length we are overwriting the result array each iteration, so that at the end only the combinations with the expected length are in the results array.
Code:
<?php
$array1 = array(1,2);
$array2 = array(4,5);
$array3 = array(7,8);
$combinations = [[]];
$data = [
$array1,
$array2,
$array3,
];
$length = count($data);
for ($count = 0; $count < $length; $count++) {
$tmp = [];
foreach ($combinations as $v1) {
foreach ($data[$count] as $v2)
$tmp[] = array_merge($v1, [$v2]);
}
$combinations = $tmp;
}
print_r($combinations);
?>
output:
Array
(
[0] => Array
(
[0] => 1
[1] => 4
[2] => 7
)
//...
[7] => Array
(
[0] => 2
[1] => 5
[2] => 8
)
)
For associative arrays you only have to do a slight modification, which is:
First assign the arrays keys to a variable with
array_keys()
, e.g.$keys = array_keys($data);
Use the keys in the second foreach loop to access the data array, means from:
foreach ($data[$count] as $v2)
to:
foreach ($data[$keys[$count]] as $v2)
How can I create every combination possible for the contents of two arrays?
A loop of this form
combos = [] //or combos = new Array(2);
for(var i = 0; i < array1.length; i++)
{
for(var j = 0; j < array2.length; j++)
{
//you would access the element of the array as array1[i] and array2[j]
//create and array with as many elements as the number of arrays you are to combine
//add them in
//you could have as many dimensions as you need
combos.push(array1[i] + array2[j])
}
}
JavaScript - Generating combinations from n arrays with m elements
Here is a quite simple and short one using a recursive helper function:
function cartesian(...args) {
var r = [], max = args.length-1;
function helper(arr, i) {
for (var j=0, l=args[i].length; j<l; j++) {
var a = arr.slice(0); // clone arr
a.push(args[i][j]);
if (i==max)
r.push(a);
else
helper(a, i+1);
}
}
helper([], 0);
return r;
}
Usage:
cartesian([0,1], [0,1,2,3], [0,1,2]);
To make the function take an array of arrays, just change the signature to function cartesian(args)
instead of using rest parameter syntax.
Combination of elements of multiple arrays
This is my attempt at getting combinations from multiple arrays(containers).
private List<List<T>> getCombination(int currentIndex, List<TempContainer<T>> containers) {
if (currentIndex == containers.size()) {
// Skip the items for the last container
List<List<T>> combinations = new ArrayList<List<T>>();
combinations.add(new ArrayList<T>());
return combinations;
}
List<List<T>> combinations = new ArrayList<List<T>>();
TempContainer<T> container = containers.get(currentIndex);
List<T> containerItemList = container.getItems();
// Get combination from next index
List<List<T>> suffixList = getCombination(currentIndex + 1, containers);
int size = containerItemList.size();
for (int ii = 0; ii < size; ii++) {
T containerItem = containerItemList.get(ii);
if (suffixList != null) {
for (List<T> suffix : suffixList) {
List<T> nextCombination = new ArrayList<T>();
nextCombination.add(containerItem);
nextCombination.addAll(suffix);
combinations.add(nextCombination);
}
}
}
return combinations;
}
The method takes a list of containers with items. e.g. Container 1 will have [a,b] and Container 2 will have [c,d,e]. The method can take any number of containers.
// The container class is declared as follows:
public class TempContainer<T> {
private List<T> items;
public void setItems(List<T> items) {
this.items = items;
}
public List<T> getItems() {
return items;
}
}
Call this method as follows:
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2");
List<String> list2 = new ArrayList<String>();
list2.add("3");
list2.add("4");
list2.add("5");
TempContainer container1 = new TempContainer();
container1.setItems(list1);
TempContainer container2 = new TempContainer();
container2.setItems(list2);
List<TempContainer> containers = new ArrayList<TempContainer>(2);
containers.add(container1);
containers.add(container2);
// Get combinations
List<List<T>> combinations = getCombination(0, containers);
Finding all possible combinations of multiple arrays (where all combinations also include all items in the array)
It isn't totally clear what your desired outcome is, but I think itertools.product()
is what you are looking for...
from itertools import product
five=["fivea","fiveb","fivec","fived"]
six=["sixa","sixb","sixc","sixd"]
seven=["sevena","sevenb","sevenc","sevend"]
my_lists = [five, six, seven]
for item in product(*my_lists):
print(item)
Yields
('fivea', 'sixa', 'sevena')
('fivea', 'sixa', 'sevenb')
('fivea', 'sixa', 'sevenc')
('fivea', 'sixa', 'sevend')
('fivea', 'sixb', 'sevena')
('fivea', 'sixb', 'sevenb')
('fivea', 'sixb', 'sevenc')
('fivea', 'sixb', 'sevend')
('fivea', 'sixc', 'sevena')
('fivea', 'sixc', 'sevenb')
('fivea', 'sixc', 'sevenc')
('fivea', 'sixc', 'sevend')
('fivea', 'sixd', 'sevena')
('fivea', 'sixd', 'sevenb')
('fivea', 'sixd', 'sevenc')
('fivea', 'sixd', 'sevend')
('fiveb', 'sixa', 'sevena')
('fiveb', 'sixa', 'sevenb')
...
('fived', 'sixd', 'sevend')
Using permutations of all elements... with shortened lists
from itertools import permutations as p
five=["fivea","fiveb"]
six=["sixa","sixb","sixc"]
seven=["sevena","sevenb"]
my_lists = [five, six, seven]
# flatten it out...
my_items = [item for sublist in my_lists for item in sublist ]
print(my_items)
for perm in p(my_items, len(my_items)):
print(perm)
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.
Get all combinations of list multiple arrays
Here is an answer using list-comprehension
import itertools
import math
def iden(x):
return x
def log(x):
return math.log(x)
def exp(x):
return 1/(1+math.exp(-x))
X = [1, 2, 3]
funcs = [iden, log, exp]
def apply(functions, values):
return [func(val) for func,val in zip(functions, values)]
values = [apply(f, X) for f in itertools.product(funcs, repeat=len(funcs))]
The apply
function seemed useful. If you don't want it, then this will do
values = [[func(val) for func,val in zip(f, X)] for f in itertools.product(funcs, repeat=len(funcs))]
Sample output
[1, 2, 3] # (iden, iden, iden)
[1, 2, 1.0986122886681096] # (iden, iden, log)
[1, 2, 0.95257412682243336] # (iden, iden, exp)
[1, 0.69314718055994529, 3] # (iden, log, iden)
Find all combinations consisting of one row per multiple arrays
Adapted from https://stackoverflow.com/a/49445693/7207392
import numpy as np
import operator as op
import itertools as it
def cartesian_product_pp(arrays, out=None):
la = len(arrays)
h, w = zip(*map(op.attrgetter('shape'), arrays))
w = np.fromiter(it.chain([0], w), int, la+ 1)
W = w.cumsum()
h = *h, W[la]
dtype = np.result_type(*arrays)
arr = np.empty(h, dtype=dtype)
arrs = *it.accumulate(it.chain((arr,), it.repeat(0, la-1)), np.ndarray.__getitem__),
idx = slice(None), *it.repeat(None, la-1)
for i in range(la-1, 0, -1):
arrs[i][..., W[i]:W[i+1]] = arrays[i][idx[:la-i]]
arrs[i-1][1:] = arrs[i]
arr[..., W[0]:W[1]] = arrays[0][idx]
return arr.reshape(-1, W[la])
# example
a = np.r_[:3].reshape(1, 3)
b = np.r_[5:20].reshape(3, 5)
c = np.r_[17:38].reshape(3, 7)
p = cartesian_product_pp([a, b, c])
Output:
>>> p
array([[ 0, 1, 2, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23],
[ 0, 1, 2, 5, 6, 7, 8, 9, 24, 25, 26, 27, 28, 29, 30],
[ 0, 1, 2, 5, 6, 7, 8, 9, 31, 32, 33, 34, 35, 36, 37],
[ 0, 1, 2, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23],
[ 0, 1, 2, 10, 11, 12, 13, 14, 24, 25, 26, 27, 28, 29, 30],
[ 0, 1, 2, 10, 11, 12, 13, 14, 31, 32, 33, 34, 35, 36, 37],
[ 0, 1, 2, 15, 16, 17, 18, 19, 17, 18, 19, 20, 21, 22, 23],
[ 0, 1, 2, 15, 16, 17, 18, 19, 24, 25, 26, 27, 28, 29, 30],
[ 0, 1, 2, 15, 16, 17, 18, 19, 31, 32, 33, 34, 35, 36, 37]])
Timings for this, @B.M.'s and @Bazingaa's approaches:
>>> timeit(lambda: cartesian_product_pp([a,b,c]), number=1000)*1000
15.173833002336323
>>> timeit(lambda: combine([a,b,c]), number=1000)*1000
31.1394709860906
>>> timeit(lambda: np.array([np.hstack((i, j, k)) for i in a for j in b for k in c]), number=1000)*1000
51.15771805867553
Related Topics
What Are .Tpl Files? PHP, Web Design
Php, Get Tomorrows Date from Date
Get the First Letter of Each Word in a String
Php: Settings Memory_Limits > 1024M Does Not Work
HTML Upload Max_File_Size Does Not Appear to Work
Codeigniter PHP Model Access "Unable to Locate the Model You Have Specified"
Should My PHP Functions Accept an Array of Arguments or Should I Explicitly Request Arguments
PHP Cli: How to Read a Single Character of Input from the Tty (Without Waiting for the Enter Key)
Executing a PHP Script with a Cron Job
How to Get Final Url After Following Http Redirections in Pure PHP
Set Session in Database in PHP
Publishing to User's Wall Without Being Online/Logged-In - Facebook Sharing Using Graph API
Get Current Url Path with Query String in PHP
Why Does PHP Convert a String with the Letter E into a Number