Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mloureiro
Last active October 9, 2015 22:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mloureiro/a0ecd1ef477e08b6b83a to your computer and use it in GitHub Desktop.
Save mloureiro/a0ecd1ef477e08b6b83a to your computer and use it in GitHub Desktop.
Make all available options from a demanded list
<?php
$sections = [
'bread' => [
'multichoice' => false,
'options' => ['normal','wrap']
],
'salad' => [
'multichoice' => true,
'options' => ['lettuce','tomatoes', 'corn']
],
'sauce' => [
'multichoice' => true,
'options' => ['mostard','ketchup']
],
'protein' => [
'multichoice' => false,
'options' => ['hamburger','tuna', 'smoked salmon']
],
];
/**
* Evaluate if it is NOT a multi dimensional array
*
* @param array $list
*
* @return bool
*/
function isFlat(array $list)
{
foreach($list as $element)
{
if(is_array($element))
{
return false;
}
}
return true;
}
/**
* Flat multi dimensional arrays into Bi dimensional (max)
*
* @param array $list
*
* @return array
*/
function flatToBiDimensionalArray(array $list)
{
if(isFlat($list))
{
return $list;
}
$final = [];
foreach($list as $element)
{
if(isFlat($element))
{
$final[] = $element;
}
else
{
$final = array_merge($final, flatToBiDimensionalArray($element));
}
}
return $final;
}
/**
* Make each element of the array into an array of itself
*
* @param array $list
*
* @return array
*/
function eachElementToArray(array $list)
{
$final = [];
foreach($list as $element)
{
$final[] = [$element];
}
return $final;
}
/**
* Generate all combinations possible without order mattering
*
* @param array $list
*
* @return array
*/
function generateAllCombinations(array $list)
{
if(count($list) === 1)
{
return $list;
}
$first = array_pop($list);
$combinations = flatToBiDimensionalArray(generateAllCombinations($list));
$final = [];
$final[] = [$first];
foreach ($combinations as $combination)
{
$final[] = is_array($combination)
? array_merge([$first], $combination)
: [$first, $combination];
}
if(isFlat($combinations))
{
$final[] = $combinations;
}
else
{
$final = array_merge($final, $combinations);
}
return $final;
}
/**
* Is similar to generateAllCombinations() but doesn't attempt to flat the arrays
*
* @param array $sections
*
* @return array
*/
function mixTogether(array $sections)
{
if(count($sections) === 1)
{
$key = key($sections);
$final = [];
foreach(array_pop($sections) as $type)
{
$final[] = [$key => $type];
}
return $final;
}
$sandwiches = [];
end($sections);
$key = key($sections);
$section = array_pop($sections);
$combinations = mixTogether($sections);
foreach($section as $type)
{
foreach($combinations as $combination)
{
$combination[$key] = $type;
$sandwiches[] = $combination;
}
}
return $sandwiches;
}
/*
*
* Script
*
*/
$iterations = 100000;
$i = 0;
$start = microtime(true);
while($i++ < $iterations)
{
// generate all combinations for each section
$sectionCombinations = [];
foreach ($sections as $id => $section)
{
$sectionCombinations[$id] = $section['multichoice']
? generateAllCombinations($section['options'])
: eachElementToArray($section['options']);
}
$sandwichList = mixTogether($sectionCombinations);
}
$end = microtime(true);
print_r($sandwichList);
$totalCombinations = count($sandwichList);
echo "\n\nTotal time for {$iterations} iterations with {$totalCombinations} combinations: " . ($end - $start) . " seconds\n";
@mloureiro
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment