Was Sie wirklich suchen, ist eine Möglichkeit, Sequenzen zu iterieren:
000
001
010
011
100
101
110
111
Es wäre auch schön, wenn wir nicht davon ausgehen müssten, dass die Größe der einzelnen Eingabefelder gleich ist. Wenn wir also die Größe des zweiten Arrays um 1 verringern:
array(
[0] => array([0]=>'blue',[1]=>'red'),
[1] => array([0]=>'sunny'),
[2] => array([0]=>'sweet',[1]=>'acid');
...wollen wir, dass der Maximalwert für diese Spalte um 1 verringert wird:
000
001
100
101
Durch diese Abstraktion wird das Problem leichter zu verstehen. Wie würden Sie diese Folge iterieren? Bei jeder Iteration erhöhen Sie die Spalte ganz rechts um 1. Wenn sie dadurch über ihr Maximum hinaus wachsen würde, setzen Sie sie auf 0 zurück und gehen eine Spalte nach links. Nun wiederholen Sie das, was Sie gerade mit der letzten Spalte gemacht haben. Wenn Sie auch diese Spalte nicht erhöhen können, setzen Sie sie auf 0 zurück, gehen nach links, spülen und wiederholen. Wenn Sie den ganzen Weg zurückgelegt haben und keine Spalte erhöhen konnten, ohne den Maximalwert zu überschreiten, sind Sie fertig.
Wir können die obige Logik in einen PHP-Iterator verpacken:
class Sequence implements Iterator {
private $input;
private $hasNext;
private $positions;
public function __construct(array $input) {
$this->input = $input;
}
public function rewind() {
$this->hasNext = true;
$this->positions = array();
for ($i = 0; $i < count($this->input); $i++) {
$this->positions[$i] = 0;
}
}
public function valid() {
return $this->hasNext;
}
public function current() {
$current = array();
for ($i = 0; $i < count($this->positions); $i++) {
$current[] = $this->input[$i][$this->positions[$i]];
}
return $current;
}
public function key() {}
public function next() {
for ($i = count($this->positions) - 1; $i >= 0; $i--) {
if ($this->positions[$i] < count($this->input[$i]) - 1) {
$this->positions[$i]++;
break;
} else {
$this->positions[$i] = 0;
$this->hasNext = $i !== 0;
}
}
}
}
next()
ist die Umsetzung der obigen Logik. reset()
setzt einfach jede Spalte auf 0 zurück und current()
verwendet die aktuelle Sequenz als die Indizes der Eingabe, um die aktuellen Werte zurückzugeben.
Hier ist sie in Aktion zu sehen (wobei "wolkig" entfernt wurde, um die Allgemeinheit der Lösung zu verdeutlichen):
$input = array(
array('blue', 'red'),
array('sunny'),
array('sweet', 'acid')
);
$lst = new Sequence($input);
foreach ($lst as $elt) {
print(implode(', ', $elt) . "\n");
}
Und seine Leistung:
blue, sunny, sweet
blue, sunny, acid
red, sunny, sweet
red, sunny, acid