From 1143a538c0790fd04fcbe6a530145887e4e1e774 Mon Sep 17 00:00:00 2001 From: Karoly Negyesi Date: Sat, 11 Oct 2014 19:43:05 -0700 Subject: [PATCH] Add associative array cartesian products --- .../CartesianAssociativeProduct.php | 94 ++++++++++++++++ .../Combination/CartesianProduct.php | 7 +- .../CartesianAssociativeProduct.php | 106 ++++++++++++++++++ 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 Combinatorics/Combination/CartesianAssociativeProduct.php create mode 100644 Test/Unit/Combinatorics/Combination/CartesianAssociativeProduct.php diff --git a/Combinatorics/Combination/CartesianAssociativeProduct.php b/Combinatorics/Combination/CartesianAssociativeProduct.php new file mode 100644 index 0000000..9e64d2e --- /dev/null +++ b/Combinatorics/Combination/CartesianAssociativeProduct.php @@ -0,0 +1,94 @@ + [1, 2], + * Y => [a, b], + * ] + * X × Y = [ [X => 1, Y => a], [X => 1, Y => b], [X => 2, Y => a], + * [X => 2, y => b] ] + * + * @author Karoly Negyesi + * @copyright Copyright © 2014 Karoly Negyesi. + * @license New BSD License + */ + +class CartesianAssociativeProduct extends CartesianProduct { + + /** + * array_keys() of the input array. + * + * @var array + */ + protected $_keys = []; + + /** + * Constructor. + * + * @access public + * @param array $array Associative array of arrays. + * @return void + */ + public function __construct ( $array ) { + + $this->_keys = array_keys($array); + $this->init($array); + } + + /** + * Prepare the current value. + * + * @access protected + * @return void + */ + protected function _current ( ) { + + $this->_current = []; + + foreach($this->_sets as $i => $set) + $this->_current[$this->_keys[$i]] = $set->current(); + + return; + } + +} diff --git a/Combinatorics/Combination/CartesianProduct.php b/Combinatorics/Combination/CartesianProduct.php index 9cb1eb9..cc079ae 100644 --- a/Combinatorics/Combination/CartesianProduct.php +++ b/Combinatorics/Combination/CartesianProduct.php @@ -103,7 +103,12 @@ class CartesianProduct implements Iterator { */ public function __construct ( $set ) { - foreach(func_get_args() as $s) { + $this->init(func_get_args()); + } + + public function init ( $input ) { + + foreach($input as $s) { if(is_array($s)) $s = new Iterator\Map($s); diff --git a/Test/Unit/Combinatorics/Combination/CartesianAssociativeProduct.php b/Test/Unit/Combinatorics/Combination/CartesianAssociativeProduct.php new file mode 100644 index 0000000..dccb37a --- /dev/null +++ b/Test/Unit/Combinatorics/Combination/CartesianAssociativeProduct.php @@ -0,0 +1,106 @@ + + * @copyright Copyright © 2014 Karoly Negyesi. + * @license New BSD License + */ + +class CartesianAssociativeProduct extends Test\Unit\Suite { + + public function case_empty ( ) { + + $this + ->given($iterator = new CAT([])) + ->when($result = iterator_to_array($iterator)) + ->then + ->array($result) + ->isEqualTo([[null]]); + } + + public function case_X ( ) { + + $this + ->given($iterator = new CAT([[1], [2], [3]])) + ->when($result = iterator_to_array($iterator)) + ->then + ->array($result) + ->isEqualTo([ + [1], + [2], + [3] + ]); + } + + public function case_X_Y ( ) { + + $this + ->given($iterator = new CAT(['X' => [1, 2, 3], 'Y' => [4, 5, 6]])) + ->when($result = iterator_to_array($iterator)) + ->then + ->array($result) + ->isEqualTo([ + ['X' => 1, 'Y' => 4], + ['X' => 2, 'Y' => 4], + ['X' => 3, 'Y' => 4], + + ['X' => 1, 'Y' => 5], + ['X' => 2, 'Y' => 5], + ['X' => 3, 'Y' => 5], + + ['X' => 1, 'Y' => 6], + ['X' => 2, 'Y' => 6], + ['X' => 3, 'Y' => 6] + ]); + } + + public function case_X_Y_Z ( ) { + + $this + ->given($iterator = new CAT(['X' => [1, 2, 3], 'Y' => [4, 5, 6], 'Z' => [7, 8, 9]])) + ->when($result = iterator_to_array($iterator)) + ->then + ->array($result) + ->isEqualTo([ + ['X' => 1, 'Y' => 4, 'Z' => 7], + ['X' => 2, 'Y' => 4, 'Z' => 7], + ['X' => 3, 'Y' => 4, 'Z' => 7], + ['X' => 1, 'Y' => 5, 'Z' => 7], + ['X' => 2, 'Y' => 5, 'Z' => 7], + ['X' => 3, 'Y' => 5, 'Z' => 7], + ['X' => 1, 'Y' => 6, 'Z' => 7], + ['X' => 2, 'Y' => 6, 'Z' => 7], + ['X' => 3, 'Y' => 6, 'Z' => 7], + + ['X' => 1, 'Y' => 4, 'Z' => 8], + ['X' => 2, 'Y' => 4, 'Z' => 8], + ['X' => 3, 'Y' => 4, 'Z' => 8], + ['X' => 1, 'Y' => 5, 'Z' => 8], + ['X' => 2, 'Y' => 5, 'Z' => 8], + ['X' => 3, 'Y' => 5, 'Z' => 8], + ['X' => 1, 'Y' => 6, 'Z' => 8], + ['X' => 2, 'Y' => 6, 'Z' => 8], + ['X' => 3, 'Y' => 6, 'Z' => 8], + + ['X' => 1, 'Y' => 4, 'Z' => 9], + ['X' => 2, 'Y' => 4, 'Z' => 9], + ['X' => 3, 'Y' => 4, 'Z' => 9], + ['X' => 1, 'Y' => 5, 'Z' => 9], + ['X' => 2, 'Y' => 5, 'Z' => 9], + ['X' => 3, 'Y' => 5, 'Z' => 9], + ['X' => 1, 'Y' => 6, 'Z' => 9], + ['X' => 2, 'Y' => 6, 'Z' => 9], + ['X' => 3, 'Y' => 6, 'Z' => 9] + ]); + } + +}