假设有三个数组(实际不确定多少个数组):
$arr1 = array(1, 2, 3, 4);
$arr2 = array(10, 20, 30, 40);
$arr3 = array(100, 200, 300, 400);要实现的结果:
array(
array(1,10,100),
array(1,10,200),
array(1,10,300),
array(1,10,400),
array(1,20,100),
array(1,20,200),
array(1,20,300),
array(1,20,400),
array(1,30,100),
...
);
不想用递归,但是也可以实现看看排列组合
$arr1 = array(1, 2, 3, 4);
$arr2 = array(10, 20, 30, 40);
$arr3 = array(100, 200, 300, 400);要实现的结果:
array(
array(1,10,100),
array(1,10,200),
array(1,10,300),
array(1,10,400),
array(1,20,100),
array(1,20,200),
array(1,20,300),
array(1,20,400),
array(1,30,100),
...
);
不想用递归,但是也可以实现看看排列组合
$b = ['A', 'B', 'C'];
$c = ['a', 'b'];
$d = ['D', 'E', 'F'];$r = Descartes($a, $b, $c);
$r = Descartes($a, $b, $c, $d);print_r( array_map(function($v) { return join(',', $v); }, $r) );function Descartes() {
$d = func_get_args();
if( count($d) < 2 ) return current($d);
$n = array_product( array_map('count', $d) );
array_walk( $d, function(&$v, $k, $n) {
$v = array_chunk( call_user_func_array('array_merge', array_pad([$v], $n/count($v), $v)), 1);
}, $n);
foreach($d as $i=>$t) {
if($i == 0) {
$r = $t;
}else {
array_multisort(array_map(function($v) { return $v[0]; }, $r), $r);
$r = array_map('array_merge', $r, $t);
}
}
return $r;
}
Array
(
[0] => 1,A,a,D
[1] => 1,A,a,E
[2] => 1,A,a,F
[3] => 1,A,b,D
[4] => 1,A,b,E
[5] => 1,A,b,F
[6] => 1,B,a,D
[7] => 1,B,a,E
[8] => 1,B,a,F
[9] => 1,B,b,D
[10] => 1,B,b,E
[11] => 1,B,b,F
[12] => 1,C,a,D
[13] => 1,C,a,E
[14] => 1,C,a,F
[15] => 1,C,b,D
[16] => 1,C,b,E
[17] => 1,C,b,F
[18] => 2,A,a,D
[19] => 2,A,a,E
[20] => 2,A,a,F
[21] => 2,A,b,D
[22] => 2,A,b,E
[23] => 2,A,b,F
[24] => 2,B,a,D
[25] => 2,B,a,E
[26] => 2,B,a,F
[27] => 2,B,b,D
[28] => 2,B,b,E
[29] => 2,B,b,F
[30] => 2,C,a,D
[31] => 2,C,a,E
[32] => 2,C,a,F
[33] => 2,C,b,D
[34] => 2,C,b,E
[35] => 2,C,b,F
)
看的有点晕,得慢慢看,用到了很多以前很少用的函数,不过这个中括号是什么写法? 5.3.12不支持
array_pad([$v], $n/count($v), $v)
$d = func_get_args();//读取传入的参数到数组(php4)
if( count($d) < 2 ) return current($d);
$n = array_product( array_map('count', $d) ); //array_product 计算数组值的乘积(php5),array_map 返回经回调函数处理的数组(php4)
array_walk( $d, function(&$v, $k, $n) {//用回调函数处理数组元素(php3)闭包写法(php5.3)
$v = array_chunk( call_user_func_array('array_merge', array_pad([$v], $n/count($v), $v)), 1);
}, $n);//array_chunk 切割数组(php4)
//call_user_func_array 调用指定函数并传递参数数组(php4)对执行可变参数数量的函数很有用
foreach($d as $i=>$t) {
if($i == 0) {
$r = $t;
}else {
array_multisort(array_map(function($v) { return $v[0]; }, $r), $r);
$r = array_map('array_merge', $r, $t);
}
}
闭包可用 create_function 函数改写
多谢版主
我自己也写了个,比较啰嗦
function arr_combina3(){
$args = func_get_args();
$num = count($args);
if(empty($args)){
return array();
}else if($num == 1){
return $args[0];
}
$arr = array();
$i = 0;
$j = 0; // 当前使用数组下标
$last_index = $num - 1;
// 按传入顺序循环使用传入的参数数组
while($j <= $last_index){
if($j == $last_index){ // 当前使用数组为最后参数数组时
// 将最后传入的参数数组每一项分别加入组合
$tmp = $arr[$i];
foreach($args[$j] as $k=>$v){
$t = $tmp;
$t[] = $v;
$arr[$i] = $t;
++$i;
}
// 反向循环查找参数数组是否已使用完
for($n=$j-1; $n>=0; --$n){
$t = current($args[$n]);
// 检测是否已到数组末尾
if(empty($t)){ // 已到数组末尾
if(0==$n){ // 已经是第一个数组的末尾,说明组合完成,停止组合
$num = 0;
break 2;
}
reset($args[$n]);
}else{ // 未到末尾时,修改当前使用数组下标
$j = $n;
// 去除已到最后的项
$arr[$i] = array_slice($tmp, 0, $n, true);
break;
}
}
unset($tmp);
}else{
// 将当前使用数组当前指针指向的值加入到组合数组
$arr[$i][] = current($args[$j]);
next($args[$j]);// 当前使用数组指针前移一位
++$j; // 当前使用数组下标+1
}
}
unset($args);
return $arr;
}
{
$args = func_get_args();
$final = array_shift($args);
while($f = array_shift($args))
{
$r = array();
foreach($final as $v)
{
foreach($f as $v2)
{
$r[] = array_merge(is_array($v)?$v:array($v),array($v2));
}
}
$final = $r;
}
return $final;
}
$arr1 = array(1, 2, 3, 4);
$arr2 = array(10, 20, 30, 40);
$arr3 = array(100, 200, 300, 400);
$data = array($arr1,$arr2,$arr3);
echo "<pre/>";
print_r(call_user_func_array('my_arr_combine', $data));