【问题标题】:PHP, make with all other array values [closed]PHP,使用所有其他数组值[关闭]
【发布时间】:2014-12-18 12:40:17
【问题描述】:

我必须用其他数组值创建一个复杂的数组。

原来的数组是:

Array (
     [0] => Array (
        [0] => A
        [1] => B
        [2] => C
    )

    [1] => Array (
        [0] => D
        [1] => E
        [2] => F
    )
)

我正在寻找一个函数,它可以为我提供所有可能的组合值,如下所示:

Array (
  [0] => Array (A, D),
  [1] => Array (A, E),
  [2] => Array (A, F),
  [3] => Array (B, D),
  [4] => Array (B, E),
  [5] => Array (B, F),
  [6] => Array (C, D),
  [7] => Array (C, E),
  [8] => Array (C, F)
)

当然,即使原始数组中的值数量不同,此算法也必须有效。

我正在 PHP 文档中寻找一个用于执行此操作的简单函数,但没有找到。

我用“multiplex”或“combine”之类的关键字搜索了它,但没有运气。我认为最好的方法是做一个递归函数,但我找不到正确的算法。

【问题讨论】:

  • 基本上你想要一个笛卡尔结果。这是一个类似示例的链接stackoverflow.com/questions/6311779/…
  • 子数组中会不断有 3 个值吗??
  • 嗨,谢谢你的回答。不,我的原始数组可能有 X 个数组条目
  • 您可以从子数组中获取所有元素并创建一个包含所有元素的临时数组,然后使用我在stackoverflow.com/a/27177761/3186769 的答案来查找所有 2 元素组合。这有帮助吗?

标签: php arrays function combiners


【解决方案1】:

计算笛卡尔积的简单递归函数:

function cartesian(array $data)
{
    function cartesian_r(array $data, array $path, &$out)
    {
        if (count($data) > 1) {
            // recursive step
            $head = array_slice($data, 0, -1);
            $tail = end($data);
            foreach ($tail as $item) {
                cartesian_r($head, array_merge($path, [$item]), $out);
            }
        } else {
            // unwind step
            foreach ($data[0] as $item) {
                $out[] = array_merge([$item], $path);
            }
        }
    }

    $out = [];
    cartesian_r($data, [], $out);

    return $out;
}

$out = cartesian([['A', 'B'], ['C', 'D'], ['E', 'F']]);

print_r($out);

输出

Array
(
    [0] => Array
        (
            [0] => A
            [1] => E
            [2] => C
        )

    [1] => Array
        (
            [0] => B
            [1] => E
            [2] => C
        )

    [2] => Array
        (
            [0] => A
            [1] => E
            [2] => D
        )

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

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

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

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

    [7] => Array
        (
            [0] => B
            [1] => F
            [2] => D
        )

)

【讨论】:

  • 这个不错,+1。但是,[] 在 5.4 之前的版本中不支持,它可以很容易地替换为 array(),并且效果一样好:phpfiddle.org/main/code/jdct-q0uf
  • @TiborB 你应该已经在使用 php 5.4 了;)
  • PHP 5.3 已停产,不再受支持,请先处理再处理 :)
  • 我通常处理 5.4+,但显然 PHPFiddle 仍然是 5.3.29 :/
  • @TiborB。我以前从未使用过 phpfiddle;我使用 eval.in 或 3v4l。
【解决方案2】:

只有两个 foreach

$first = array('A', 'B', 'C', 'D');
$second = array('E', 'F', 'G');

$result = array();
foreach ($first as $f) {
    foreach ($second as $s) {
        $result[] = array($f, $s);
    }
}
var_dump($result);

【讨论】:

  • Thks 但我不知道子数组的数量。因此,如果子数组超过 2 个,您的代码将无法正常工作。
  • 如果有第三个呢?那么输出应该是什么?
  • 简单,那么每个输出元素包含三个元素。
  • 所有这些组合?然后有点难,但使用递归函数可以做到。
  • 是的,就像this one :)
【解决方案3】:

这适用于尽可能多的 sub_arrays .. 它不像原始输出那样排序,但可以使用示例中的排序函数轻松修复:

 $input = array(
    0 => array ('A','B','C'),
    1 => array ('D','E','F'),
    2 => array ('X','Y','Z'),
    /*...*/
);

$result = array();  
foreach($input as $sub_arr){
    $_result = array();
    foreach($sub_arr as $val){
        if($result){
            foreach($result as $old){
                $old[] = $val;
                $_result[] = $old;
            }
        }else{ 
            $_result[] = array($val);
        }
    }
    $result = $_result;
} 
array_multisort($result); //sort all layers alphabetically.
echo "<pre>";
print_r($result);

工作示例:Fiddle

【讨论】:

  • 我认为这个在没有递归函数的情况下模拟递归值得一票。
  • 它解决了任务......并且没有必要使用递归。 (除非是家庭作业)。
【解决方案4】:

这是我能想象到的最简单的动态:

它显示“所有可能的组合”

<?php

$origArray = array(
    array(
         "A",
         "B",
         "C"        
    ),
     array(
        "D",
        "E",
        "F"     
    )
);

$endArray = array();

foreach ($origArray as $key_1 => $value_1){
    foreach ($origArray as $key_2 => $value_2){
        if($key_1 == $key_2){
            continue;
        }
        foreach($value_1 as $key_1_1 => $value_1_1 ){
            foreach ($value_2 as $key_2_1 => $value_2_1){
                $endArray[] = array($value_1_1, $value_2_1);
            }
        }


    }

}
echo "<pre>";
var_dump($endArray);
echo "</pre>";

如果你想显示你可以使用的第一个子数组的所有组合:

<?php

$origArray = array(
    array(
         "A",
         "B",
         "C"        
    ),
     array(
        "D",
        "E",
        "F"     
    )
);

$endArray = array();

foreach ($origArray as $key_1 => $value_1){
    foreach($origArray[0] as $key_1_1 => $value_1_1 ){
        if($key_1 == 0 ){
            continue;
        }
        foreach ($value_1 as $key_2_1 => $value_2_1){

            $endArray[] = array($value_1_1, $value_2_1);
        }
    }
}
echo "<pre>";
var_dump($endArray);
echo "</pre>";

【讨论】:

  • echo count($endArray) // 18
  • 第二个例子 == 9 ,但不是所有组合,而是与第一个子数组的所有组合
  • OP 忘了提到数组可以包含两个以上的元素。
  • 是的,然后这段代码仍然有效。
  • 它的工作原理是它不会崩溃,但是具有三个元素的输入数组的预期输出应该是三个一组。
猜你喜欢
  • 1970-01-01
  • 2015-08-25
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
相关资源
最近更新 更多