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种类型的视频卡(可选)
'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种类型