Php 如何生成多个数组的所有唯一组合';有可选的吗?

Php 如何生成多个数组的所有唯一组合';有可选的吗?,php,arrays,combinations,Php,Arrays,Combinations,我希望将多个数组中的所有值组合起来,以创建唯一的组合。有一个缺点:一些数组可以是可选的 例如:我正在配置一台电脑,我可以选择: 5种机箱(包括风扇、PSU和主板) 5种类型的磁盘(可选) 5种类型的内存(可选) 5种类型的视频卡(可选) 如您所见,结果可以是以下任意组合: 机箱类型1、磁盘类型3、内存类型5、视频卡类型1 机箱类型1、磁盘类型3、内存类型5、视频卡类型2 机箱类型1、磁盘类型3、内存类型5、视频卡类型3 机箱类型1,无磁盘,内存类型5,视频卡类型2 机箱类型1,无磁盘,内存类

我希望将多个数组中的所有值组合起来,以创建唯一的组合。有一个缺点:一些数组可以是可选的

例如:我正在配置一台电脑,我可以选择:

  • 5种机箱(包括风扇、PSU和主板)
  • 5种类型的磁盘(可选)
  • 5种类型的内存(可选)
  • 5种类型的视频卡(可选)
如您所见,结果可以是以下任意组合:

  • 机箱类型1、磁盘类型3、内存类型5、视频卡类型1
  • 机箱类型1、磁盘类型3、内存类型5、视频卡类型2
  • 机箱类型1、磁盘类型3、内存类型5、视频卡类型3
  • 机箱类型1,无磁盘,内存类型5,视频卡类型2
  • 机箱类型1,无磁盘,内存类型5,无视频卡
  • 机箱类型1,无磁盘、无内存、无视频卡
  • 等等
  • 为了确定一系列产品是否可选,数组中包含了
    'optional'=>[0 | 1]
    部分:-)

    以下数组是“生产”中使用的数组的摘录,应合并:

    array(
        array('optional' => 0, 0, 1),
        array('optional' => 0, 3, 4),
        array('optional' => 0, 6, 7, 8),
        array('optional' => 1, 6, 7, 8, 2),
        array('optional' => 1, 6, 7, 8, 5, 9),
        array('optional' => 1, 6, 7, 8, 10, 11, 12)
    )
    
    输出应该类似于:

    0, 3, 6
    0, 3, 7
    0, 3, 8
    0, 4, 6
    0, 4, 7
    0, 4, 8
    1, 3, 6
    1, 3, 7
    1, 3, 8
    [...]
    0, 3, 6, 2  <-- outcome with an optional product from the 4th array
    0, 3, 7, 9  <-- outcome with an optional product from the 5th array
    0, 3, 8, 12 <-- outcome with an optional product from the 6th array
    
    该函数工作完美,所以我想使用类似的东西,准确地说,我不想失去发电机的功能,因为它是真正的内存友好(我以前的函数会在返回可用输出之前组合所有内容,在4GB内存下只能返回320万个组合。这个函数在测试中已经以千倍的速度通过了320万个组合)

    目前,我还希望包括可选的数组,以便也生成这些数组:-)

    请注意:我喜欢速度,但对于这个功能来说,这并不重要,因为它将作为后台作业运行,没有任何用户交互


    我希望有人能帮助我:-)

    看来答案比理解问题要简单得多。 您不需要更改过程-只需在可选数组中包含“null”作为可能的值。这意味着这部分不包括在内

    这样,将有返回空值的数组,但它们的索引将表示源。以下面的数组为例:

    $data = array(
        'Chassis'   => array(0, 1, 2),
        'Mainboard' => array(3, 4, 5),
        'PSU'       => array(6, 7, 8),
        'Disk'      => array(null, 9, 10),
        'GFX'       => array(null, 11, 12),
        'Memory'    => array(null, 13, 14, 15)
    );
    
    其中一个结果是:
    [0,3,6,null,11,null]
    *这意味着包含了GFX

    如果不希望使用空值,可以过滤该结果

    array_filter($combination, 'is_int')
    
    “is_int”
    参数仅用于正确处理
    0
    。如果
    0
    不是有效的id,则可以跳过它(然后可以使用
    0
    而不是null)

    *)实际上,由于
    array\u merge()
    args顺序,最后一个元素跳到第一个位置

    编辑: 此生成器本身的速度快约35%(内存使用量相同),并且不需要过滤,总体速度是原来的两倍:

    function generateCombinations(array $array) {
        foreach (array_pop($array) as $id) {
            if (empty($array)) {
                yield isset($id) ? [$id] : [];
                continue;
            }
    
            foreach (generateCombinations($array) as $combination) {
                if (isset($id)) { $combination[] = $id; }
                yield $combination;
            }
        }
    }
    

    答案似乎比理解问题要简单得多。 您不需要更改过程-只需在可选数组中包含“null”作为可能的值。这意味着这部分不包括在内

    这样,将有返回空值的数组,但它们的索引将表示源。以下面的数组为例:

    $data = array(
        'Chassis'   => array(0, 1, 2),
        'Mainboard' => array(3, 4, 5),
        'PSU'       => array(6, 7, 8),
        'Disk'      => array(null, 9, 10),
        'GFX'       => array(null, 11, 12),
        'Memory'    => array(null, 13, 14, 15)
    );
    
    其中一个结果是:
    [0,3,6,null,11,null]
    *这意味着包含了GFX

    如果不希望使用空值,可以过滤该结果

    array_filter($combination, 'is_int')
    
    “is_int”
    参数仅用于正确处理
    0
    。如果
    0
    不是有效的id,则可以跳过它(然后可以使用
    0
    而不是null)

    *)实际上,由于
    array\u merge()
    args顺序,最后一个元素跳到第一个位置

    编辑: 此生成器本身的速度快约35%(内存使用量相同),并且不需要过滤,总体速度是原来的两倍:

    function generateCombinations(array $array) {
        foreach (array_pop($array) as $id) {
            if (empty($array)) {
                yield isset($id) ? [$id] : [];
                continue;
            }
    
            foreach (generateCombinations($array) as $combination) {
                if (isset($id)) { $combination[] = $id; }
                yield $combination;
            }
        }
    }
    

    你想有一个选择,包括可选的,你的意思是?因为如果你只想包含可选的,那么里面就没有可选的。这是正确的,可以选择包含可选的产品,但你不必这样做。例如:我正在配置一台PC,我可以选择5种机箱(包括风扇、PSU和主板)、5种磁盘(可选)、5种内存和5种视频卡(可选)。如您所见,结果可以是以下任意组合:
    机箱类型1、磁盘类型3、内存类型5、视频卡类型4。机箱类型1,无磁盘,内存类型5,视频卡类型2。机箱类型1,无磁盘,内存类型5,无显卡。
    因此阵列中的
    'optional'=>[0 | 1]
    部分:-)如果可选为0或1,则您只能获得所有可选组合或无,因此您的
    [0,3,6,2]
    作为选项从第4个阵列(仅)将永远不会生成,因为您还选择了第5和第6个选项。结果数组中可能有3个或6个元素。您需要一种方法来确定是否选择了该选项。感谢您的回答:-)可选产品(内存、视频卡等)没有链接,因此其中一个可以是可选的,但另一个也可以是强制性的。可选产品在管理界面中通过“生成可选触发器”进行设置。我们检查哪些产品可以合并,哪些不能合并;然后,我们对产品(即内存)进行分组,并制作兼容的产品组组合。因此,
    [0,3,6,2]
    是可能的。我希望您理解:-)所以结果应该是所有3到6个字段的组合(因为最后3个字段是可选的),对吗?这个数据结构可以更改吗?或者已经实现了吗?您想选择包含可选的吗?因为如果你只想包含可选的,那么里面就没有可选的。这是正确的,可以选择包含可选的产品,但你不必这样做。例如:我正在配置一台PC,我可以选择5种机箱类型(包括风扇、PSU和主板)、5种磁盘类型(可选)、5种类型