PHP 2D数组输出所有组合
我已经有这个问题弯腰了一会儿(头冷也没有帮助!),基本上我有一个PHP数组,看起来像这个例子:
$array[0][0] = 'apples'; $array[0][1] = 'pears'; $array[0][2] = 'oranges'; $array[1][0] = 'steve'; $array[1][1] = 'bob';
而且我希望能够从这个表格中产生这些表格的每一种可能的组合,但是不需要重复任何组合(不pipe它们的位置),所以例如这将输出
Array 0 Array 1 apples steve apples bob pears steve pears bob
但是我希望能够尽可能多的使用不同的数组。
这被称为“笛卡尔产品”,数组的PHP手册页http://php.net/manual/en/ref.array.php显示了一些实现(在评论中)。;
还有另外一个:
function array_cartesian() { $_ = func_get_args(); if(count($_) == 0) return array(array()); $a = array_shift($_); $c = call_user_func_array(__FUNCTION__, $_); $r = array(); foreach($a as $v) foreach($c as $p) $r[] = array_merge(array($v), $p); return $r; } $cross = array_cartesian( array('apples', 'pears', 'oranges'), array('steve', 'bob') ); print_r($cross);
你正在寻找数组的笛卡尔积,并有一个PHP数组网站的例子: http : //php.net/manual/en/ref.array.php
Syom复制http://www.php.net/manual/en/ref.array.php#54979,但我调整它成为一个联合版本:;
function array_cartesian($arrays) { $result = array(); $keys = array_keys($arrays); $reverse_keys = array_reverse($keys); $size = intval(count($arrays) > 0); foreach ($arrays as $array) { $size *= count($array); } for ($i = 0; $i < $size; $i ++) { $result[$i] = array(); foreach ($keys as $j) { $result[$i][$j] = current($arrays[$j]); } foreach ($reverse_keys as $j) { if (next($arrays[$j])) { break; } elseif (isset ($arrays[$j])) { reset($arrays[$j]); } } } return $result; }
我需要做同样的事情,我尝试了之前发布的解决scheme,但无法使其工作。 我从这个聪明的人得到了一个样本http://www.php.net/manual/en/ref.array.php#54979 。 然而,他的样本没有pipe理不重复组合的概念。 所以我包含了这个部分 这是我的修改版本,希望它可以帮助:
$data = array( array('apples', 'pears', 'oranges'), array('steve', 'bob') ); $res_matrix = $this->array_cartesian_product( $data ); foreach ( $res_matrix as $res_array ) { foreach ( $res_array as $res ) { echo $res . " - "; } echo "<br/>"; } function array_cartesian_product( $arrays ) { $result = array(); $arrays = array_values( $arrays ); $sizeIn = sizeof( $arrays ); $size = $sizeIn > 0 ? 1 : 0; foreach ($arrays as $array) $size = $size * sizeof( $array ); $res_index = 0; for ( $i = 0; $i < $size; $i++ ) { $is_duplicate = false; $curr_values = array(); for ( $j = 0; $j < $sizeIn; $j++ ) { $curr = current( $arrays[$j] ); if ( !in_array( $curr, $curr_values ) ) { array_push( $curr_values , $curr ); } else { $is_duplicate = true; break; } } if ( !$is_duplicate ) { $result[ $res_index ] = $curr_values; $res_index++; } for ( $j = ( $sizeIn -1 ); $j >= 0; $j-- ) { $next = next( $arrays[ $j ] ); if ( $next ) { break; } elseif ( isset ( $arrays[ $j ] ) ) { reset( $arrays[ $j ] ); } } } return $result; }
结果会是这样的:
苹果 – 史蒂夫
苹果 – 鲍勃
梨 – 史蒂夫
梨 – 鲍勃
橘子 – 史蒂夫
橘子 – 鲍勃
如果你的数据数组是这样的:
$data = array( array('Amazing', 'Wonderful'), array('benefit', 'offer', 'reward'), array('Amazing', 'Wonderful') );
然后它会打印这样的东西:
惊人的 – 好处 – 太好了
惊人的 – 提供 – 美好的
惊人的 – 奖励 – 精彩
精彩 – 收益 – 令人惊叹
精彩 – 提供 – 令人惊叹
精彩 – 奖励 – 惊人
foreach($parentArray as $value) { foreach($subArray as $value2) { $comboArray[] = array($value, $value2); } }
不要评价我
我认为这是有效的 – 尽pipe在写完之后我意识到它与其他人所做的非常相似,但它确实会按照请求的格式给出一个数组。 对不起,variables命名。
$output = array(); combinations($array, $output); print_r($output); function combinations ($array, & $output, $index = 0, $p = array()) { foreach ( $array[$index] as $i => $name ) { $copy = $p; $copy[] = $name; $subIndex = $index + 1; if (isset( $array[$subIndex])) { combinations ($array, $output, $subIndex, $copy); } else { foreach ($copy as $index => $name) { if ( !isset($output[$index])) { $output[$index] = array(); } $output[$index][] = $name; } } } }
@ user187291
我修改这是
function array_cartesian() { $_ = func_get_args(); if (count($_) == 0) return array(); $a = array_shift($_); if (count($_) == 0) $c = array(array()); else $c = call_user_func_array(__FUNCTION__, $_); $r = array(); foreach($a as $v) foreach($c as $p) $r[] = array_merge(array($v), $p); return $r; }
所以当你传递0个参数时,它将返回所有重要的空数组(结果与无组合相同)。
只有注意到这一点,因为我使用它
$combos = call_user_func_array('array_cartesian', $array_of_arrays);
function array_comb($arrays) { $result = array(); $arrays = array_values($arrays); $sizeIn = sizeof($arrays); $size = $sizeIn > 0 ? 1 : 0; foreach ($arrays as $array) $size = $size * sizeof($array); for ($i = 0; $i < $size; $i ++) { $result[$i] = array(); for ($j = 0; $j < $sizeIn; $j ++) array_push($result[$i], current($arrays[$j])); for ($j = ($sizeIn -1); $j >= 0; $j --) { if (next($arrays[$j])) break; elseif (isset ($arrays[$j])) reset($arrays[$j]); } } return $result; }
我必须从产品选项进行组合。 这个解决scheme使用recursion,并使用2D数组:
function options_combinations($options) { $result = array(); if (count($options) <= 1) { $option = array_shift($options); foreach ($option as $value) { $result[] = array($value); } } else { $option = array_shift($options); $next_option = options_combinations($options); foreach ($next_option as $next_value) { foreach ($option as $value) { $result[] = array_merge($next_value, array($value)); } } } return $result; } $options = [[1,2],[3,4,5],[6,7,8,9]]; $c = options_combinations($options); foreach ($c as $combination) { echo implode(' ', $combination)."\n"; }
基于本地Python函数itertools.product
优雅实现
function direct_product(array ...$arrays) { $result = [[]]; foreach ($arrays as $array) { $tmp = []; foreach ($result as $x) { foreach ($array as $y) { $tmp[] = array_merge($x, [$y]); } } $result = $tmp; } return $result; }
在MySQL数据库中会是这样的:
SELECT * FROM `options`, `groups`
就这样 :)