Heim > Backend-Entwicklung > PHP-Tutorial > 对多个数组进行组合讨论

对多个数组进行组合讨论

WBOY
Freigeben: 2016-06-23 14:21:40
Original
889 Leute haben es durchsucht

排列组合

假设有三个数组(实际不确定多少个数组):
$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),
    ...
);
不想用递归,但是也可以实现看看

回复讨论(解决方案)

本帖最后由 xuzuning 于 2013-09-12 07:58:13 编辑

$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;}
Nach dem Login kopieren
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        ))
Nach dem Login kopieren

嗯,这个是对的。#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;}
Nach dem Login kopieren
Nach dem Login kopieren
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)
Nach dem Login kopieren
Nach dem Login kopieren

嗯,这个是对的。#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;}
Nach dem Login kopieren
Nach dem Login kopieren
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)
Nach dem Login kopieren
Nach dem Login kopieren


看的有点晕,得慢慢看,用到了很多以前很少用的函数,不过这个中括号是什么写法? 5.3.12不支持
array_pad([$v], $n/count($v), $v)
Nach dem Login kopieren

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);    }  }
Nach dem Login kopieren

除了简化 array() 为 [], 和使用了闭包写法外,没有什么新东西
闭包可用 create_function 函数改写

除了简化 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;}
Nach dem Login kopieren

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));
Nach dem Login kopieren
Nach dem Login kopieren

不现丑了,收藏了再说。

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));
Nach dem Login kopieren
Nach dem Login kopieren

这个简单明了 
Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage