Created
December 4, 2013 10:54
-
-
Save xphere/7785740 to your computer and use it in GitHub Desktop.
Iterates over all combinations of the values on an input array
This file contains hidden or 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 | |
| class CombinatorialIterator implements \Iterator | |
| { | |
| protected $valid; | |
| protected $iteration; | |
| protected $data; | |
| public function __construct(array $data = array()) | |
| { | |
| $this->data = $data; | |
| } | |
| public function current() | |
| { | |
| $result = array(); | |
| foreach ($this->data as $name => $value) { | |
| $result[$name] = is_array($value) ? current($value) : $value; | |
| } | |
| return $result; | |
| } | |
| public function next() | |
| { | |
| $this->valid = false; | |
| foreach ($this->data as $name => $value) { | |
| if (is_array($value)) { | |
| next($this->data[$name]); | |
| if (key($this->data[$name]) !== null) { | |
| $this->valid = true; | |
| break; | |
| } | |
| reset($this->data[$name]); | |
| } | |
| } | |
| ++$this->iteration; | |
| } | |
| public function key() | |
| { | |
| return $this->iteration; | |
| } | |
| public function valid() | |
| { | |
| return $this->valid; | |
| } | |
| public function rewind() | |
| { | |
| $this->valid = !empty($this->data); | |
| $this->iteration = 0; | |
| foreach ($this->data as $name => $value) { | |
| if (is_array($value)) { | |
| reset($this->data[$name]); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or 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 | |
| class CombinatorialIteratorTest extends \PHPUnit_Framework_TestCase | |
| { | |
| public function testEmptyConstruction() | |
| { | |
| $iterator = new CombinatorialIterator(); | |
| $this->assertNotNull($iterator); | |
| } | |
| /** | |
| * @dataProvider providerValidInput | |
| */ | |
| public function testValidInput($input, $expected) | |
| { | |
| $this->assertEquals($expected, iterator_to_array(new CombinatorialIterator($input))); | |
| } | |
| public function providerValidInput() | |
| { | |
| return array( | |
| 'default' => array( | |
| array(), | |
| array(), | |
| ), | |
| 'single scalar' => array( | |
| array('scalar' => 'value'), | |
| array( | |
| array('scalar' => 'value'), | |
| ), | |
| ), | |
| 'multiple scalar' => array( | |
| array('scalar1' => 'value1', 'scalar2' => 'value2'), | |
| array( | |
| array('scalar1' => 'value1', 'scalar2' => 'value2'), | |
| ), | |
| ), | |
| 'single array' => array( | |
| array('option' => array('first', 'second')), | |
| array( | |
| array('option' => 'first'), | |
| array('option' => 'second'), | |
| ), | |
| ), | |
| 'multiple array' => array( | |
| array( | |
| 'name' => array('Bob', 'John'), | |
| 'surname' => array('Spongebob', 'Snow'), | |
| ), | |
| array( | |
| array('name' => 'Bob', 'surname' => 'Spongebob', ), | |
| array('name' => 'John', 'surname' => 'Spongebob', ), | |
| array('name' => 'Bob', 'surname' => 'Snow', ), | |
| array('name' => 'John', 'surname' => 'Snow', ), | |
| ), | |
| ), | |
| 'mixed' => array( | |
| array(array('A', 'B'), 'C', array('D', 'E', 'F'), 'G'), | |
| array( | |
| array('A', 'C', 'D', 'G'), | |
| array('B', 'C', 'D', 'G'), | |
| array('A', 'C', 'E', 'G'), | |
| array('B', 'C', 'E', 'G'), | |
| array('A', 'C', 'F', 'G'), | |
| array('B', 'C', 'F', 'G'), | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment