您可以枚举结果集的元素,即对于 0....(元素数量)-1 之间的每个整数,您可以判断要返回哪个元素(即存在自然顺序)。对于给定的示例:
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]
您只需要一个(整数)索引n和一个将索引“转换”为(自然有序)集合的第n个元素的函数。由于您只需要一个整数来存储当前状态,因此当您拥有许多/大型数组时,内存消耗不会“爆炸”。正如克里斯在他的评论中所说,您可以用速度(使用较小的集合时)换取低内存消耗。(虽然我认为 - 实现 php 的方式 - 这也是一个合理的快速解决方案。)
$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";
}
您可以使用它来实现例如Iterator、SeekableIterator甚至可能是ArrayAccess(从而与递归解决方案相比,反转控制,几乎就像yield
在 python 或 ruby 中的 a )
<?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; }
}
印刷
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
(顺序似乎没问题;-))