Created
April 22, 2014 20:30
-
-
Save jwage/11193216 to your computer and use it in GitHub Desktop.
PHP Cartesian Function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$attributeValues = array( | |
'color' => array('Red', 'White', 'Blue'), | |
'size' => array(1, 2, 3, 4), | |
'fabric' => array('Cloth', 'Silk') | |
); | |
class Cartesian | |
{ | |
public static function build($set) | |
{ | |
if (!$set) { | |
return array(array()); | |
} | |
$subset = array_shift($set); | |
$cartesianSubset = self::build($set); | |
$result = array(); | |
foreach ($subset as $value) { | |
foreach ($cartesianSubset as $p) { | |
array_unshift($p, $value); | |
$result[] = $p; | |
} | |
} | |
return $result; | |
} | |
} | |
print_r(Cartesian::build($attributeValues)); |
Author
jwage
commented
Apr 22, 2014
What about an iterator? Would be much better for memory usage. An implementation exists here: Hoa\Math\Combinatorics\Combination\CartesianProduct
. Thus:
$product = new Hoa\Math\Combinatorics\Combination\CartesianProduct(
['Red', 'White', 'Blue'],
[1, 2, 3, 4],
['Cloth', 'Silk']
);
foreach($product as $i => $tuple)
echo $i, ' = (', implode(', ', $tuple), ')', "\n";
would be product:
0 = (Red, 1, Cloth)
1 = (White, 1, Cloth)
2 = (Blue, 1, Cloth)
3 = (Red, 2, Cloth)
4 = (White, 2, Cloth)
5 = (Blue, 2, Cloth)
6 = (Red, 3, Cloth)
7 = (White, 3, Cloth)
8 = (Blue, 3, Cloth)
9 = (Red, 4, Cloth)
10 = (White, 4, Cloth)
11 = (Blue, 4, Cloth)
12 = (Red, 1, Silk)
13 = (White, 1, Silk)
14 = (Blue, 1, Silk)
15 = (Red, 2, Silk)
16 = (White, 2, Silk)
17 = (Blue, 2, Silk)
18 = (Red, 3, Silk)
19 = (White, 3, Silk)
20 = (Blue, 3, Silk)
21 = (Red, 4, Silk)
22 = (White, 4, Silk)
23 = (Blue, 4, Silk)
👍
If i need a certain amount of data, what should i do?
suppose i need maximum 20 data instead of 24 from you above example, then what should i do?
There looks to be 24 combinations; for the universe to balanced 24 must be returned. If you do not want all of them you can slice off the ones you don't want. $array = array_slice($array, 0, 20);
or $array = array_slice($array, 4, 24);
.
btw @jwage
return CartesianProduct::build([
$this->xmlProvider()[0],
$this->validElementNameProvider()[0],
$this->invalidElementNameProvider()[0]
]);
nice one.
Here's pretty interesting implementation https://github.com/PatchRanger/cartesian-iterator
Amazing. Thanks a Ton
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment