Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP 2D数组输出所有组合_Php_Arrays_Recursion_Multidimensional Array - Fatal编程技术网

PHP 2D数组输出所有组合

PHP 2D数组输出所有组合,php,arrays,recursion,multidimensional-array,Php,Arrays,Recursion,Multidimensional Array,我有一段时间一直在思考这个问题(头脑发冷也没用!),基本上我有一个PHP数组,看起来像这个例子: $array[0][0] = 'apples'; $array[0][1] = 'pears'; $array[0][2] = 'oranges'; $array[1][0] = 'steve'; $array[1][1] = 'bob'; 我希望能够从中生成一个包含所有可能组合的表,但不重复任何组合(无论其位置如何),例如,这将输出 Array 0 Array 1 app

我有一段时间一直在思考这个问题(头脑发冷也没用!),基本上我有一个PHP数组,看起来像这个例子:

$array[0][0] = 'apples';
$array[0][1] = 'pears';
$array[0][2] = 'oranges';

$array[1][0] = 'steve';
$array[1][1] = 'bob';
我希望能够从中生成一个包含所有可能组合的表,但不重复任何组合(无论其位置如何),例如,这将输出

Array 0            Array 1
apples             steve
apples             bob
pears              steve
pears              bob
但我希望它能够使用尽可能多的不同数组。

这被称为“笛卡尔产品”,数组上的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);

我认为这是可行的——虽然在写了它之后,我意识到它与其他人所写的非常相似,但它确实提供了所需格式的数组。很抱歉变量命名不好

$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;   
            }
        }
    }
}
@用户187291

我把这个改成

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);

您正在寻找数组的笛卡尔乘积,php数组站点上有一个示例:

不要评判我

函数数组\u comb($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;
}
{ $result=array(); $arrays=数组值($arrays); $sizeIn=sizeof($arrays); $size=$sizeIn>0?1:0; foreach($array作为$array) $size=$size*sizeof($array); 对于($i=0;$i<$size;$i++) { $result[$i]=array(); 对于($j=0;$j<$sizeIn;$j++) 数组推送($result[$i],current($arrays[$j]); 对于($j=($sizeIn-1);$j>=0;$j--) { if(下一个($arrays[$j])) 打破 elseif(isset($arrays[$j])) 重置($arrays[$j]); } } 返回$result; }
Syom复制了它,但我将其改编为关联版本:

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;
}
函数数组\u笛卡尔($array){
$result=array();
$keys=数组\ U键($arrays);
$reverse\u keys=数组\u reverse($keys);
$size=intval(计数($arrays)>0);
foreach($array作为$array){
$size*=计数($array);
}
对于($i=0;$i<$size;$i++){
$result[$i]=array();
foreach($j){
$result[$i][$j]=当前($array[$j]);
}
foreach($j){
if(下一个($arrays[$j])){
打破
}
elseif(isset($arrays[$j])){
重置($arrays[$j]);
}
}
}
返回$result;
}

我也需要这样做,我尝试了这里发布的以前的解决方案,但无法使它们工作。我从这个聪明人那里得到了一个样本。然而,他的样本并没有实现无重复组合的概念。所以我包括了那部分。这是我修改过的版本,希望有帮助:

$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;
}
然后它将打印如下内容:

惊人-收益-精彩
精彩-优惠-精彩
惊人-奖励-精彩
精彩-收益-精彩
精彩-优惠-精彩

精彩-奖励-精彩

我必须根据产品选项进行组合。此解决方案使用递归并与二维数组配合使用:

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";
}
功能选项\u组合($options){
$result=array();

if(count($options)基于本机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;
}

是否会有数组2、数组3、数组N?还是只有两个数组?您好,很抱歉没有说得更清楚,可能会有数组2、数组3到数组N。谢谢。您需要的是在SQL中轻松完成交叉连接,但在PHPAs中需要一些思考。这可能来自mySQL数据库,所有选项(苹果、梨、橙子、steve、bob等)在一个表工具包中,是否有另一个表的键定义了它们所属的组(水果、人等),有什么办法可以在mysql中使用吗?重复:如果这个函数存在于一个类中,您可能希望更改user\u func调用,如下所示:
$c=call\u user\u func\u array(array($this,\u function\uuu),$)
。此外,它还可以发出警告(不是数组)如果输入数组大小不相等。这是一个很好的解决方案,但第一次短路的结果是真实的,这对我来说没有意义。试试看。
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";
}
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;
}