对多个数组进行组合讨论

ywq0127 2013-09-11 05:27:15
假设有三个数组(实际不确定多少个数组):
$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),
...
);
不想用递归,但是也可以实现看看
...全文
195 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hx_Moon_ 2013-09-12
  • 打赏
  • 举报
回复
不现丑了,收藏了再说。
foolbirdflyfirst 2013-09-12
  • 打赏
  • 举报
回复
function my_arr_combine()
{
	$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));
ywq0127 2013-09-12
  • 打赏
  • 举报
回复
引用 5 楼 xuzuning 的回复:
除了简化 array() 为 [], 和使用了闭包写法外,没有什么新东西 闭包可用 create_function 函数改写
嗯,5.3没有这种语法。怎么感觉php的语法和javascript的越来越像 多谢版主 我自己也写了个,比较啰嗦
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;
}
xuzuning 2013-09-12
  • 打赏
  • 举报
回复
除了简化 array() 为 [], 和使用了闭包写法外,没有什么新东西 闭包可用 create_function 函数改写
xuzuning 2013-09-12
  • 打赏
  • 举报
回复
array() 可简化为 [] 是 php5.4 才有的吗?我怎么记得 php5.3 就是的呢? 简单注释一下:
  $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);
    }
  }
ywq0127 2013-09-12
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
嗯,这个是对的。#1 的有些毛病,传入4个数组就不对了
$a = [1, 2];
$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)
xuzuning 2013-09-12
  • 打赏
  • 举报
回复
嗯,这个是对的。#1 的有些毛病,传入4个数组就不对了
$a = [1, 2];
$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
)
xuzuning 2013-09-12
  • 打赏
  • 举报
回复
$a = [1, 2];
$b = ['A', 'B', 'C'];
$c = ['a', 'b'];

$d = Descartes($a, $b, $c);
print_r($d);

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);
if($k==0) sort($v);
}, $n);
array_unshift($d, 'array_merge');
$d = call_user_func_array('array_map', $d);
array_multisort(array_map(function($v) { return $v[0]; }, $d), $d);
return $d;
}
Array
(
[0] => Array
(
[0] => 1
[1] => A
[2] => a
)

[1] => Array
(
[0] => 1
[1] => A
[2] => b
)

[2] => Array
(
[0] => 1
[1] => B
[2] => a
)

[3] => Array
(
[0] => 1
[1] => B
[2] => b
)

[4] => Array
(
[0] => 1
[1] => C
[2] => a
)

[5] => Array
(
[0] => 1
[1] => C
[2] => b
)

[6] => Array
(
[0] => 2
[1] => A
[2] => a
)

[7] => Array
(
[0] => 2
[1] => A
[2] => b
)

[8] => Array
(
[0] => 2
[1] => B
[2] => a
)

[9] => Array
(
[0] => 2
[1] => B
[2] => b
)

[10] => Array
(
[0] => 2
[1] => C
[2] => a
)

[11] => Array
(
[0] => 2
[1] => C
[2] => b
)

)
ywq0127 2013-09-12
  • 打赏
  • 举报
回复
引用 7 楼 foolbirdflyfirst 的回复:
function my_arr_combine()
{
	$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));
这个简单明了

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧