从n个数组生成具有m个元素的组合,每个元素使用不同的次数

时间:2015-01-01 16:46:38

标签: javascript arrays combinations

下面的代码 - Generating combinations from n arrays with m elements - 几乎就是我要找的,但是,如果我需要从每个数组中获取不同数量的元素,该怎么办呢。

考虑这些数据......

[[0,1,2,3,4], 
 [0,1,2,3,4,5,6], 
 [0,1,2,3,4,5,6,7],
 [0,1,2,3],
 [0,1,2,3,4],
 [0,1,2,3,4]
]

如果我想从第一个数组中获取1个元素,从第二个数组获取2个元素,从第三个数据中获取3个,然后从其余数据中获取1个,每个输出数组总共有9个元素。

        function cartesian() {
            var r = [], arg = arguments, max = arg.length-1;
            function helper(arr, i) {
                for (var j=0, l=arg[i].length; j<l; j++) {
                    var a = arr.slice(0); // clone arr
                    a.push(arg[i][j])
                    if (i==max) {
                        r.push(a);
                    } else
                        helper(a, i+1);
                }
            }
            helper([], 0);
            return r;
        };

上面的代码几乎完美,但它只从每个数组中抓取一个元素,显然arg.length只看到六个参数而不是arg1中的首选1,arg2中的2个,3来自arg3,1来自arg4,1来自arg5,1来自arg6

最后,但不是那么重要(我想尝试自己想出这个部分),从我抓住多个元素的一个组中,每个元素只能使用一次。

我应该提一下,每个元素实际上都是一个json对象,而不仅仅是一个简单的数字。使用上面的代码,无关紧要。

如果有帮助,我可以用以下方法计算可能性的总数:

//this is not in any particular language, just a large calculation
//its a simple factorial for Combinations - n!/r!(n-r)!
//lets say we have only 10 objects in each of the 9 arrays...
//10 * 9 = total of 90 objects in the pool.
(factorial(90))/((factorial(9))*(factorial(90 - 9))) = **706,252,528,634**

数字变得非常高,因为每个数组最多可包含80个对象。

感谢。

更新 在玩了不少之后,我已经走得很远......现在我有一个完全不同的问题,我可能会在其他地方重新发布。 这里的输出是MASSSIIIVVVEEEE。在四元组中,如果我只采用每个数组10个小样本集。 Javascript只是耗尽内存并在所有经过测试的主流浏览器中崩溃(chrome,即firefox,safari)。将发布为另一个问题,然后在此处发布链接。

1 个答案:

答案 0 :(得分:0)

count = 0;
past = false;
arr = [];
data = [[0,1,2,3,4], [0,1,2,3,4,5,6], [0,1,2,3,4,5,6,7], [0,1,2,3], [0,1,2,3,4], [0,1,2,3,4]];

for(i=0; i<data.length; i++){ //iterate through data length
    if(count<3 && !past){ //check if it should go up 1
        count++;
    }else if(!past){ //reset to 1
        count = 1;
        past = true;
    }
    arr.push(data[i][count]); //add to new array
}

alert(arr); //alert final result