javascript对象多属性值实现笛卡尔积

var obj = {
'渠道': ["a", "b"], 
'城市': ["邯郸市", "武汉"], 
'stage': ["注册", "阶段一", "阶段二", "阶段三"], 
‘date’: ["最近7天", "最近14天", "最近28天"]
}

要形成一系列数组如下['a', '武汉','注册','最近七天']

我现在的方式是把对象变成二维数组,然后实现

function cartesianProductOf(obj) {  var test = obj.map(item => item);   
 return Array.prototype.reduce.call(test,function(a, b) {    var ret = [];
        a.forEach(function(a) {
        b.forEach(function(b) {
        ret.push(a.concat([b]));
      });
    });   return ret;
  }, [[]]);
}console.log(cartesianProductOf(a))

想问还有什么更好的方法,因为考虑到后期数据量大的问题


陪伴而非守候
浏览 833回答 1
1回答

呼如林

要看你拿这个积中的元素来干什么,如果仅仅是每行,则其实这个问题换一个思路很好解决。所谓笛卡尔积,其实质是全组合可能,这样所有可能其实可以映射为一个多位二进制整数,这个整数的每个区段对应一个原组合(1维数组),这样只要能取得一个值范围内的数,就可以很快确定一个最后积里的一行(顺序可能不严格了,但可以保证单独的行肯定是在最后数组中)。我们分析你原始的数据,var&nbsp;obj&nbsp;=&nbsp;{'渠道':&nbsp;["a",&nbsp;"b"],&nbsp;//可以对应1bit'城市':&nbsp;["邯郸市",&nbsp;"武汉"],//可以对应1bit'stage':&nbsp; ["注册",&nbsp;"阶段一",&nbsp;"阶段二",&nbsp;"阶段三"],//可以对应2bit'date':&nbsp;["最近7天",&nbsp;"最近14天",&nbsp;"最近28天"]//可以对应2bit,不过要过滤11}这样所有的可能就映射到1个6bit的整数上,且该值的最后2bit不能是11然后可以直接从0-(2^6-1)中过滤掉最后是11的数字就是每行有效映射,可以反解析出实际元素组合。比如0这个数字可以对应[a,"邯郸市","注册","最近7天"]而63因为最后2bit是11,不符合,62则对应[b, "武汉","阶段三","最近28天"]要输出所有的组合(每1行)也很简单了(注意顺序不一定对)let&nbsp;outarr=[]; for(let&nbsp;i=0;i<64;i++){ &nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;(i&0x3)!==3&nbsp;){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;tmp=[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.put(obj['渠道'][i>>5]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.put(obj['城市'][(i>>4)&0X1]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.put(obj['stage'][(i>>2)&0X3]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.put(obj['date'][i&0X3]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outarr.put(tmp); &nbsp;&nbsp;&nbsp;&nbsp;} }这样处理的好处是不涉及复杂的矩阵计算了,扩展性很好,效率也很高(是一个O(n)时间复杂度的算法,内存消耗也比较小,唯一不足是顺序性不符合严格的笛卡尔积)这就要看你如何用这些数据了。另外建议你所有的代码都采用markdown格式处理,可以发现一些代码中的问题的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript