为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

陪伴而非守候 2018-10-19 10:41:07
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))想问还有什么更好的方法,因为考虑到后期数据量大的问题
查看完整描述

1 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

要看你拿这个积中的元素来干什么,如果仅仅是每行,则其实这个问题换一个思路很好解决。
所谓笛卡尔积,其实质是全组合可能,这样所有可能其实可以映射为一个多位二进制整数,这个整数的每个区段对应一个原组合(1维数组),这样只要能取得一个值范围内的数,就可以很快确定一个最后积里的一行(顺序可能不严格了,但可以保证单独的行肯定是在最后数组中)。

我们分析你原始的数据,

var obj = {'渠道': ["a", "b"], //可以对应1bit'城市': ["邯郸市", "武汉"],//可以对应1bit'stage': 
["注册", "阶段一", "阶段二", "阶段三"],//可以对应2bit'date': ["最近7天", "最近14天", "最近28天"]//可以对应2bit,不过要过滤11}

这样所有的可能就映射到1个6bit的整数上,且该值的最后2bit不能是11
然后可以直接从0-(2^6-1)中过滤掉最后是11的数字就是每行有效映射,可以反解析出实际元素组合。
比如0这个数字可以对应[a,"邯郸市","注册","最近7天"]
而63因为最后2bit是11,不符合,62则对应[b, "武汉","阶段三","最近28天"]
要输出所有的组合(每1行)也很简单了(注意顺序不一定对)

let outarr=[];
for(let i=0;i<64;i++){
    if( (i&0x3)!==3 ){
        let tmp=[];
        tmp.put(obj['渠道'][i>>5]);
        tmp.put(obj['城市'][(i>>4)&0X1]);
        tmp.put(obj['stage'][(i>>2)&0X3]);
        tmp.put(obj['date'][i&0X3]);
        outarr.put(tmp);
    }
}

这样处理的好处是不涉及复杂的矩阵计算了,扩展性很好,效率也很高(是一个O(n)时间复杂度的算法,内存消耗也比较小,唯一不足是顺序性不符合严格的笛卡尔积)这就要看你如何用这些数据了。


另外建议你所有的代码都采用markdown格式处理,可以发现一些代码中的问题的。


查看完整回答
反对 回复 2018-11-05
  • 1 回答
  • 0 关注
  • 832 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号