Sie die Elemente der r aufzählen Es wird für jede ganze Zahl zwischen 0 .... (Anzahl der Elemente) -1 angegeben, welches Element zurückgegeben werden soll (d. h.es gibt eine natürliche Reihenfolge). Für das gegebene Beispiel:
0 => array1[0], array2[0], array3[0]
1 => array1[0], array2[0], array3[1]
2 => array1[0], array2[1], array3[0]
7 => array1[1], array2[1], array3[1]
Alles, was Sie brauchen, ist ein (integer) Index n und eine Funktion, die der Index des n te Element des (natürlich bestellt) Satzes „übersetzt“. Da Sie nur eine ganze Zahl benötigen, um den aktuellen Zustand zu speichern, "explodiert" der Speicherverbrauch nicht, wenn Sie viele/große Arrays haben. Wie Chris in seinem Kommentar sagte, tauscht man die Geschwindigkeit (bei Verwendung kleinerer Sets) gegen geringen Speicherverbrauch. (Obwohl ich -der Weg php denken ist implemented- dies ist auch eine vernünftige schnelle Lösung.)
$array1 = array('dog', 'cat');
$array2 = array('food', 'tooth');
$array3 = array('car', 'bike');
function foo($key /* , ... */) {
$params = func_get_args();
$rv = array();
$key = array_shift($params);
$i=count($params);
while(0 < $i--) {
array_unshift($rv, $params[$i][ $key % count($params[$i]) ]);
$key = (int)($key/count($params[$i]));
}
return $rv;
}
for($i=0; $i<8; $i++) {
$a = foo($i, $array1, $array2, $array3);
echo join(', ', $a), "\n";
}
diese Weise können Sie zum Beispiel implementieren ein Iterator, ein SeekableIterator oder vielleicht sogar ein ArrayAccess (und damit das Umkehren der Steuerung im Vergleich zu den rekursiven Lösungen, fast wie ein yield
in Python oder Ruby)
<?php
$array1 = array('dog', 'cat', 'mouse', 'bird');
$array2 = array('food', 'tooth', 'brush', 'paste');
$array3 = array('car', 'bike', 'plane', 'shuttlecraft');
$f = new Foo($array1, $array2, $array3);
foreach($f as $e) {
echo join(', ', $e), "\n";
}
class Foo implements Iterator {
protected $data = null;
protected $limit = null;
protected $current = null;
public function __construct(/* ... */) {
$params = func_get_args();
// add parameter arrays in reverse order so we can use foreach() in current()
// could use array_reverse(), but you might want to check is_array() for each element.
$this->data = array();
foreach($params as $p) {
// <-- add: test is_array() for each $p -->
array_unshift($this->data, $p);
}
$this->current = 0;
// there are |arr1|*|arr2|...*|arrN| elements in the result set
$this->limit = array_product(array_map('count', $params));
}
public function current() {
/* this works like a baseX->baseY converter (e.g. dechex())
the only difference is that each "position" has its own number of elements/"digits"
*/
// <-- add: test this->valid() -->
$rv = array();
$key = $this->current;
foreach($this->data as $e) {
array_unshift($rv, $e[$key % count($e)]);
$key = (int)($key/count($e));
}
return $rv;
}
public function key() { return $this->current; }
public function next() { ++$this->current; }
public function rewind() { $this->current = 0; }
public function valid() { return $this->current < $this->limit; }
}
druckt
dog, food, car
dog, food, bike
dog, food, plane
dog, food, shuttlecraft
dog, tooth, car
dog, tooth, bike
[...]
bird, paste, bike
bird, paste, plane
bird, paste, shuttlecraft
(die Sequenz scheint in Ordnung zu sein ;-))
Willst du auch * Hund *, * Katze *, * Hundefutter *, * Hundezahn *, * Katzenfutter *, * Katzenzahn * oder nur die Kombinationen aller Felder kombiniert? – Gordon
Nur die Kombination aller Arrays für dieses spezielle Problem, obwohl das auch interessant zu sehen wäre. – hookedonwinter
Wenn Sie mit 100 Arrays der Größe 100 arbeiten möchten, haben Sie schwerwiegende Speicherprobleme, wenn Sie versuchen, ein Array zu generieren. Die Anzahl der Kombinationen ist eine wirklich enorme Zahl. Dies ist ein kartesisches Produkt. Sie benötigen einen Iterator. Bei diesem Ansatz wird Zeit für Speicherplatz vergeudet, da er langsamer ist, Sie aber innerhalb der Speichergrenzen bleiben können. Ich würde einen Link posten, aber es wäre hier auf der Website eines aktiven Mitglieds. Wenn er nicht alleine kommt und antwortet, werde ich den Link posten. Aber sonst will ich seinen Ruhm nicht stehlen. – goat