首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何生成多个数组与选项的所有唯一组合?

如何生成多个数组与选项的所有唯一组合?
EN

Stack Overflow用户
提问于 2016-10-04 20:48:48
回答 1查看 843关注 0票数 0

我想结合多个数组中的所有值来创建唯一的组合。有一个问题:某些数组可以是可选的。

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

  • 5种底盘(包括风扇、PSU和主板)
  • 5种类型的磁盘(可选)
  • 5种类型的内存(可选)
  • 5种类型的视频卡(可选)

正如您所看到的,结果可以是任意一个组合:

  1. 底盘类型1,磁盘类型3,内存类型5,显卡类型1
  2. 底盘类型1,磁盘类型3,内存类型5,显卡类型2
  3. 底盘类型1,磁盘类型3,内存类型5,显卡类型3
  4. 底盘类型1,没有磁盘,内存类型5,显卡类型2
  5. 底盘类型1,没有磁盘,内存类型5,没有显卡
  6. 底盘类型1,没有磁盘,没有内存,没有显卡。
  7. 等。

要确定产品的范围是否是可选的,'optional' => [0|1]部件已经包含在数组中:-)

下面的数组是应该组合在一起的用于“生产”的数组的摘录:

代码语言:javascript
运行
复制
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)
)

输出应该类似于:

代码语言:javascript
运行
复制
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

如您所见,上面的数组被组合成一个数组。其中一些子数组是强制性的,其中可选= 0,或可选其中可选= 1。

在出现可选数组之前,我使用了以下函数:

代码语言:javascript
运行
复制
<?PHP
function generateCombinations(array $array) {
    foreach (array_pop($array) as $value) {
        if (count($array)) {
            foreach (generateCombinations($array) as $combination) {
                yield array_merge([$value], $combination);
            };
        } else {
            yield [$value];
        }
    }
}
?>

这是通过以下方式使用的:

代码语言:javascript
运行
复制
foreach ( generateCombinations($ArrCombinateMe) as $combination ){
    // Some code here
}

这个函数工作得很完美,所以我想使用类似的东西,准确地说,我不想失去生成器功能,因为它确实是内存友好型的(我以前的函数在返回可用输出之前将所有东西组合在一起,在4GB内存下只能返回320万个组合)。这个函数在测试期间已经通过了320万次,达到了一千倍)。

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

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

我希望有人能帮我-)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-05 20:30:25

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

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

代码语言:javascript
运行
复制
$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被包括在内。

如果不希望使用

代码语言:javascript
运行
复制
array_filter($combination, 'is_int')

只需要'is_int' param才能正确处理0。如果0无效,那么您可以跳过它(然后可以使用0而不是null )

*)实际上,由于array_merge() args命令,最后一个元素跳到了第一个位置。

编辑:

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

代码语言:javascript
运行
复制
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;
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39861500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档