【发布时间】:2014-03-31 20:05:38
【问题描述】:
我要解决的问题是我想生成一个数组,它代表源数组中元素的所有组合。
给定 2 个项目的输入,有 4 种组合(这里表示为二进制)
第 1 组 | 0 | 1 | 0 | 1
第 2 组 | 0 | 0 | 1 | 1
--------------------------
&结果 | 0 | 1 | 2 | 3
这可以概括,所以组合的数量是 2(组数)(所以 3 个组有 8 个组合,4 个有 16 个等等)。
所以问题是;给定一个javascript数组:
var groups = [
{
name:"group1",
bit: 1
},
{
name:"group2",
bit: 2
},
{
name:"group3",
bit: 4
}];
我需要生成一个数组,其中索引表示 bit 属性的与,并且数组的值是任意的(进一步计算 - 不相关),所以我们只需将其设为组名数组(出于这个问题的目的)。这个结果是可取的:
var result = [
{groups: []}, //0
{groups: ["group1"]}, //1
{groups: ["group2"]}, //2
{groups: ["group1","group2"]}, //3
{groups: ["group3"]}, //4
{groups: ["group1","group3"]}, //5
{groups: ["group2","group3"]}, //6
{groups: ["group1","group2","group3"]} //7
]
您可以在那里的 cmets 中看到,数组中的每个索引都表示与原始的 bit 属性相匹配的行为。
我已经准备了一个jsfiddle,其中包含输入和所需的输出,如果它有助于回答问题。
This is my current solution,基于mellamokb's answer,但以我喜欢的风格重新编写。我希望有一个更优雅的解决方案,因为这对数组有很多不必要的迭代。有更好的解决方案吗?
var resultCount = Math.pow(2,groups.length);
var result = [];
for(var i=0;i<resultCount;i++){
result.push({
groups: $.map(groups, function(e,idx){
return ((i & Math.pow(2,idx)) != 0)
? e.name
: null
})
});
}
【问题讨论】:
-
解决方案是否需要担心性能?您预计拥有的最大输入组数量是多少?
-
实践中最大的组数是 4(所以 16 个组合)。实际上,我会谨慎行事,并期望可能有 6 个。
-
您能解释一下哪些迭代是不必要的吗?如果您想列举所有可能性,我看不出如何将问题减少到小于 (length^3) 次迭代。
-
@tau - 唯一不必要的组合是相反的组合。所有组合都是必需的。
标签: javascript arrays combinations