javascript 中多个对象数组的笛卡尔积

Cartesian product on multiple array of objects in javascript

我一直在研究单个元素和对象数组的笛卡尔积。对于单个数组元素,我已经理解了解决方案,但对于我难以实现的对象数组。 例如输入

cartesianProductOf([{col1:'A'}], [{col2:'B'},{col3:'C'}]) 

输出:

[{col1:'A',col2:'B'},{col1:'A',col3:'C'}]

这是我正在处理的函数

function cartesianProductOf() {
     return Array.prototype.reduce.call(arguments, function(a, b) {

         var ret = [];
         debugger;

         a.forEach(function(a) {
                 b.forEach(function(b) {
                 var r = a.concat([b])
                 ret.push(r);
             });
         });

         return ret;

    }, [[]]);
}

这个函数返回这个结果

[{col1:'A'},{col2:'B'}],[{col1:'A'},{col3:'C'}]

需要指导。

您想合并对象,而不是使用数组来推送:

function cartesianProductOf() {
     return Array.prototype.reduce.call(arguments, function(a, b) {
         var ret = [];
         a.forEach(function(a_el) {
             b.forEach(function(b_el) {
                 ret.push(Object.assign({}, a_el, b_el));
//                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             });
         });
         return ret;
    }, [{}]);
//      ^^
}

如果您不想使用 Object.assign 或者它是 polyfill,则等效项是

                 var r = {};
                 for (var p in a_el)
                     r[p] = a_el[p];
                 for (var p in b_el)
                     r[p] = b_el[p];
                 ret.push(r);

这是一个使用 Ramda.js

的解决方案

const cartesianProduct = (...Xs) =>
  R.reduce(
    (Ys, X) =>
      R.map(R.apply(R.append), R.xprod(X, Ys)), 
    [[]],
    Xs
  )

const cartesianProductOf = (...objs) =>
  R.map(R.mergeAll, cartesianProduct(...objs))

console.log(
  cartesianProductOf(
    [{col1: 'A'}],[{col2: 'B'}, {col3: 'C'}],
  )
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>