陪伴而非守候
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格式處理,可以發現一些代碼中的問題的。
添加回答
舉報
0/150
提交
取消