2个阵列的笛卡尔积

时间:2013-09-29 17:15:33

标签: javascript jquery

我有2个阵列,我想要一个笛卡尔积。举个例子:

客户数组:

[10,A]
[11,B]

Debtor数组:

[88,W]
[99,X]

我想用:

生成一个新的customerDebtor数组
[10,A,88,W]
[10,A,99,X]
[11,B,88,W]
[11,B,99,X]

我正在尝试使用此代码:

for (var i = 0; i < customerArray.length; i++) {
    for (var l = 0; l < debtorArray.length; l++) {
        $.each(customerArray[i], function (ndx, val) {
            //???? push values into customerDebtorMatrix array
        });
    }
}

4 个答案:

答案 0 :(得分:3)

你不需要jquery:

var customerArray = [[10,'A'],[11,'B']];
var debtorArray = [[88,'W'],[99,'X']];

var customerDebtorMatrix = [];
for (var i = 0; i < customerArray.length; i++) {
    for (var l = 0; l < debtorArray.length; l++) {
        customerDebtorMatrix.push(customerArray[i].concat(debtorArray[l]));
    }
}

customerDebtorMatrix

[ [ 10, 'A', 88, 'W' ],
  [ 10, 'A', 99, 'X' ],
  [ 11, 'B', 88, 'W' ],
  [ 11, 'B', 99, 'X' ] ]

答案 1 :(得分:3)

concatMap在这里运作良好:

(function() {
    'use strict';

    // cartProd :: [a] -> [b] -> [[a, b]]
    function cartProd(xs, ys) {
        return [].concat.apply([], xs.map(function (x) {
            return [].concat.apply([], ys.map(function (y) {
                return [[x, y]];
            }));
        }));
    }

    return cartProd(["alpha", "beta", "gamma"], [1, 2, 3]);

})(); 

返回:

[["alpha", 1], ["alpha", 2], ["alpha", 3], ["beta", 1], ["beta", 2], ["beta", 3], ["gamma", 1], ["gamma", 2], ["gamma", 3]]

答案 2 :(得分:2)

2017版

使用您的数据:

// Customer Array:
let c = [[10, 'A'], [11, 'B']];
// Debtor Array:
let d = [[88, 'W'], [99, 'X']];

您只需要一行:

let r = [].concat(...c.map(c => (d.map(d => c.concat(d)))));

或者这与不支持扩展语法的旧浏览器兼容:

let r = [].concat.apply([], c.map(c => (d.map(d => c.concat(d)))));

您可以看到console.log(r);打印:

[ [ 10, 'A', 88, 'W' ],
  [ 10, 'A', 99, 'X' ],
  [ 11, 'B', 88, 'W' ],
  [ 11, 'B', 99, 'X' ] ]

这正是你想要的。

没有循环,没有推送到数组,没有jQuery,只是一些简单的函数调用。

对于两个以上的数组,请参阅以下答案:

答案 3 :(得分:0)

实际上这将是Kronecker (or Tensor) Product

2个阵列的kronecker产品的Javascript代码

function kronecker_product(a, b) 
{
    var i, j, k, al = a.length, bl = b.length, abl = al*bl, ab = new Array(abl);
    i = 0; j = 0;
    for (k=0; k<abl; k++)
    {
        if ( j>=bl) {j=0; i++;}
        ab[k] = [].concat(a[i],b[j]);
        j++;
    }
    return ab;
}

为了消除歧义,让我给出笛卡尔积的代码:

function cartesian_product(a, b) 
{
    var al = a.length, bl = b.length;
    return [a.concat(bl>al ? new Array(bl-al) : []), b.concat(al>bl ? new Array(al-bl) : [])];
}

主要区别在于最终结果的组件数(长度),在kronecker中长度应该是长度的乘积,而在笛卡尔中它应该是总和。

示例Kronecker

var a = ["a","b"], b = ["c","d"];
console.log(kronecker_product(a,b));

<强>输出

[["a", "c"], ["a", "d"], ["b", "c"], ["b", "d"]]

示例笛卡儿

var a = ["a","b"], b = ["c","d"];
console.log(cartesian_product(a,b));

<强>输出

 [["a", "b"], ["c", "d"]]