Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP: Get all combinations of multiple arrays (preserves keys)
<?php
function get_combinations($arrays) {
$result = array(array());
foreach ($arrays as $property => $property_values) {
$tmp = array();
foreach ($result as $result_item) {
foreach ($property_values as $property_value) {
$tmp[] = array_merge($result_item, array($property => $property_value));
}
}
$result = $tmp;
}
return $result;
}
$combinations = get_combinations(
array(
'item1' => array('A', 'B'),
'item2' => array('C', 'D'),
'item3' => array('E', 'F'),
)
);
var_dump($combinations);
?>
array (size=8)
0 =>
array (size=3)
'item1' => string 'A' (length=1)
'item2' => string 'C' (length=1)
'item3' => string 'E' (length=1)
1 =>
array (size=3)
'item1' => string 'A' (length=1)
'item2' => string 'C' (length=1)
'item3' => string 'F' (length=1)
2 =>
array (size=3)
'item1' => string 'A' (length=1)
'item2' => string 'D' (length=1)
'item3' => string 'E' (length=1)
3 =>
array (size=3)
'item1' => string 'A' (length=1)
'item2' => string 'D' (length=1)
'item3' => string 'F' (length=1)
4 =>
array (size=3)
'item1' => string 'B' (length=1)
'item2' => string 'C' (length=1)
'item3' => string 'E' (length=1)
5 =>
array (size=3)
'item1' => string 'B' (length=1)
'item2' => string 'C' (length=1)
'item3' => string 'F' (length=1)
6 =>
array (size=3)
'item1' => string 'B' (length=1)
'item2' => string 'D' (length=1)
'item3' => string 'E' (length=1)
7 =>
array (size=3)
'item1' => string 'B' (length=1)
'item2' => string 'D' (length=1)
'item3' => string 'F' (length=1)
@subash1979

This comment has been minimized.

Copy link

@subash1979 subash1979 commented Dec 6, 2016

This is great , thanks

@mgsmus

This comment has been minimized.

Copy link

@mgsmus mgsmus commented Jan 4, 2018

I used for generating product variants (SKU) by given attribute values (color, size, material etc). Very helpful.

@lezhnev74

This comment has been minimized.

Copy link

@lezhnev74 lezhnev74 commented Jan 5, 2018

Nice, it looks like exactly what I was after.
I wonder if there is a similar functionality implemented in C.

@FlashT

This comment has been minimized.

Copy link

@FlashT FlashT commented Jan 26, 2018

Thanx!

@xsavitch

This comment has been minimized.

Copy link

@xsavitch xsavitch commented Feb 7, 2018

Please what is the best way to insert those combinations after checking if doesn't exist already in my table.
Table1(id_combinations,prix,quantity)
Table2(id_table,item,id_combinations)

Exemple :
Table1(1,"150euro",50)
Table1(2,"120euro",20)

Table2(1,"red",1)
(2,"small",1)
(3,"red",2)
(4,"big",2)

thanks

@prasadmadv

This comment has been minimized.

Copy link

@prasadmadv prasadmadv commented Mar 6, 2018

WOrks like a charm! Thanks.

@vinodselvin

This comment has been minimized.

Copy link

@vinodselvin vinodselvin commented Mar 12, 2018

Nicely done.

@simo-vt

This comment has been minimized.

Copy link

@simo-vt simo-vt commented May 15, 2018

Perfect! Thank you!

@sohaibshaheen

This comment has been minimized.

Copy link

@sohaibshaheen sohaibshaheen commented Jun 7, 2018

Helped me save hours. Thanks :)

@AlexeyKosov

This comment has been minimized.

Copy link

@AlexeyKosov AlexeyKosov commented Jun 18, 2018

Heads up: if keys are integer, array_merge should be replaced with array_replace

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Jun 28, 2018

Finally work, thanks to both @cecilemuller and @AlexeyKosov

@IAkumaI

This comment has been minimized.

Copy link

@IAkumaI IAkumaI commented Sep 7, 2018

Thanks, you saved my time :)

@reymonzakhary

This comment has been minimized.

Copy link

@reymonzakhary reymonzakhary commented Oct 9, 2018

This great, but I have big array so if I run your script stops on the have of the combination because of the memory eny idea how to fixe this?

@daiwai

This comment has been minimized.

Copy link

@daiwai daiwai commented Nov 14, 2018

Thanks for sharing. The array_merge is not necessary, though. Setting the new $property_value on $result_item[$property] directly, instead of using array_merge speeds up the function by a factor of about 2, depending on the input.

E.g. replace line 9 with:

$result_item[$property] = $property_value;
$tmp[] = $result_item;
@stephanokrm

This comment has been minimized.

Copy link

@stephanokrm stephanokrm commented Apr 23, 2019

Work's great, thank's!

@vipinks

This comment has been minimized.

Copy link

@vipinks vipinks commented Apr 27, 2019

Thanks Buddy.

@ajenkins198621

This comment has been minimized.

Copy link

@ajenkins198621 ajenkins198621 commented Jun 21, 2019

Huge help! Thanks!

@mshahzaibwiztech

This comment has been minimized.

Copy link

@mshahzaibwiztech mshahzaibwiztech commented Jul 24, 2019

It's really helpful thanks

@raufp6

This comment has been minimized.

Copy link

@raufp6 raufp6 commented Aug 26, 2019

thanks very helpful!!

@kwazaro

This comment has been minimized.

Copy link

@kwazaro kwazaro commented Aug 26, 2019

Nice gist, thanks!

@danielcmm

This comment has been minimized.

Copy link

@danielcmm danielcmm commented Aug 27, 2019

Saved me! Thanks!

@tsecheng

This comment has been minimized.

Copy link

@tsecheng tsecheng commented Sep 3, 2019

very short code and helpful!Thanks

@programadorsergio

This comment has been minimized.

Copy link

@programadorsergio programadorsergio commented Sep 18, 2019

function get_combinations($arrays) {

$arrays = array_filter($arrays); //for empty index case

$result = array(array());
foreach ($arrays as $property => $property_values) {
	$tmp = array();
	foreach ($result as $result_item) {
		foreach ($property_values as $property_value) {
			$tmp[] = array_merge($result_item, array($property => $property_value));
		}
	}
	$result = $tmp;
}
return $result;

}

@isteshkov

This comment has been minimized.

Copy link

@isteshkov isteshkov commented Nov 13, 2019

Thanks! Very helpful!

@rajitha-bandara

This comment has been minimized.

Copy link

@rajitha-bandara rajitha-bandara commented Nov 14, 2019

Saved big hours

@pankaj-torinit

This comment has been minimized.

Copy link

@pankaj-torinit pankaj-torinit commented Jan 16, 2020

Many thanks!

@kadiiskiFFW

This comment has been minimized.

Copy link

@kadiiskiFFW kadiiskiFFW commented Oct 25, 2020

Many many thanks!
You saved me so much time!

@suvo98

This comment has been minimized.

Copy link

@suvo98 suvo98 commented Nov 7, 2020

thanx. it's very helpful

@mariusadam

This comment has been minimized.

Copy link

@mariusadam mariusadam commented Jan 28, 2021

Thanks, it helped me as well. At first I didn't understand why it does exactly what I want, even covering the case of one the arrays being empty, but doing a step by step execution clarified things. Nice job!

@spiritgulshan

This comment has been minimized.

Copy link

@spiritgulshan spiritgulshan commented Feb 27, 2021

Thanks...saved my day

@dernoun

This comment has been minimized.

Copy link

@dernoun dernoun commented Mar 16, 2021

The solution works but it's extremely expansive in term time complexity, it will take O(n^) where ^ = number of arrays + 1.
I suggest this solution that is written in Java and accept any Type, put all your arrays inside one array and execute your task

public static <T> void getNumberOfOptions(List<List<T>> arr) {
	// Number of arrays
	int n = arr.size();

	// To keep track of next element in 
	// each of the n arrays
	int []indices = new int[n];

	// Initialize with first element's index
	for(int i = 0; i < n; i++)
		indices[i] = 0;
	while (true)
	{

		// Print current combination
		for(int i = 0; i < n; i++) {
			System.out.print(
					arr.get(i).get(indices[i]) + " ");
		}

		System.out.println();

		// Find the rightmost array that has more
		// elements left after the current element 
		// in that array
		int next = n - 1;
		while (next >= 0 && 
				(indices[next] + 1 >= 
				arr.get(next).size()))
			next--;

		// No such array is found so no more 
		// combinations left
		if (next < 0)
			break;


		// If found move to next element in that 
		// array
		indices[next]++;

		// For all arrays to the right of this 
		// array current index again points to 
		// first element
		for(int i = next + 1; i < n; i++)
			indices[i] = 0;
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment