简体   繁体   English

查找数组中元素的所有组合

[英]Find all combinations of elements in an array

The problem I am trying to solve is that I want to generate an array which represents all combinations of elements in a source array. 我试图解决的问题是我想生成一个数组,该数组代表源数组中元素的所有组合。

Given an input of 2 items, there are 4 combinations (represented here as binary) 给定2个项目的输入,共有4种组合(此处表示为二进制)

Group 1 | 第1组| 0 | 0 | 1 | 1 | 0 | 0 | 1 1个
Group 2 | 第2组| 0 | 0 | 0 | 0 | 1 | 1 | 1 1个
-------------------------- --------------------------
&Result | &结果| 0 | 0 | 1 | 1 | 2 | 2 | 3 3

This can be generalised so the number of combinations is 2 (number of groups) (So 3 groups has 8 combinations, 4 has 16 etc). 这可以被概括为组合数为2 (组数) (因此3个组具有8个组合,4个具有16个等)。

So the question is; 所以问题是; given a javascript array: 给定一个javascript数组:

var groups = [
{
    name:"group1",
    bit: 1
},
{
    name:"group2",
    bit: 2
},
{
    name:"group3",
    bit: 4
}];

I need to generate an array where the index represents the and'ing of the bit property and the value of the array is arbitrary (further calculation - not relevant) so lets just make it an array of the group names (for the purpose of this question). 我需要生成一个数组,其中索引表示bit属性的和,并且数组的值是任意的(进一步的计算-不相关),因此仅使它成为组名称的数组即可(出于此目的)题)。 This result is desirable: 此结果是可取的:

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
]

You can see in the comments there that each index in the array represents the act of and'ing the bit property from the original. 您可以在评论那里,阵列中的每个索引代表AND'ing的的行为见bit从原来的属性。

I have prepared a jsfiddle with the input and required output should it be useful in answering the question. 我准备了一个jsfiddle,其中包含输入和必需的输出,如果它对回答问题有用的话。


This is my current solution , based on mellamokb's answer but re-written in my prefered style. 这是我目前的解决方案 ,基于mellamokb的答案,但以我偏爱的风格重写。 I was hoping there was a more elegant solution as this has a lot of iterations over the array which are unecessary. 我希望有一个更优雅的解决方案,因为它在数组上有很多不必要的迭代。 Any better solutions? 有更好的解决方案吗?

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
        })
    });
}

Here is a relatively efficient solution that builds up the arrays by index: 这是一个相对有效的解决方案,可通过索引构建数组:

var result = [];
var resultCount = Math.pow(2, groups.length);

for (var i = 0; i < resultCount; i++) {
    result[i] = { groups: [] };
    for (var g = 0; g < groups.length; g++) {
        if (i & groups[g].bit) result[i].groups.push(groups[g].name);
    }
}

Demo: http://jsfiddle.net/7ZsHL/9/ 演示: http//jsfiddle.net/7ZsHL/9/

I think you can do it without having to store the bit and what not. 我认为您可以做到这一点而不必存储位和不存储什么。

var groups = [
    "group1",
    "group2",
    "group3",
    "group4"
];

var output = [];
for (var i = 0; i < Math.pow(2, groups.length); i++) {
    var arr = [];
    output.push(arr);
    for (var j = 0; j < groups.length; j++) {
        if (i & (Math.pow(2, j))) {
            arr.push(groups[j]);
        } else {
            arr.push(0);
        }
    }
}

I like what others have done, but in a situation like this, I might choose to be a little mover verbose in my code, as the intent of the algorithm is hard to communicate. 我喜欢别人所做的事情,但是在这种情况下,由于算法的意图难以传达,因此我可能会选择在代码中稍加改动。

An Update Of Your Fiddle 小提琴的更新

var groups = [
    {
        name:"group1",
        bit: 1
    },
    {
        name:"group2",
        bit: 2
    },
    {
        name:"group3",
        bit: 4
    }];

function parseIterations(groups){
    var aIterations = [];
    var aBits = [];
    var iGroups = groups.length;
    var iTotalIterations = Math.pow(2, iGroups);
    for (var i = 0; i < iTotalIterations; i++) {
        var oIteration = { groups: [] };
        for (var j = 0; j < iGroups; j++) {
            if (typeof aBits[j] == 'undefined')
                aBits[j] = true;
            // while you could infer the .bit value from j, 
            // i've chosen to use your .bit value here.
            aBits[j] = (i % groups[j].bit == 0) ? !aBits[j] : aBits[j];
            if (aBits[j])
                oIteration.groups.push(groups[j].name);
        }
        aIterations[i] = oIteration;
    }
    return aIterations;
}

var result = parseIterations(groups);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM