2015-01-17 106 views
1

考慮下面的代碼:反向笛卡爾積

function cartesianProductOf() { 
    return _.reduce(arguments, function(a, b) { 
     return _.flatten(_.map(a, function(x) { 
      return _.map(b, function(y) { 
       return x.concat([y]); 
      }); 
     }), true); 
    }, [ [] ]); 
}; 

var cp = cartesianProductOf([1, 2], [3, 4], ['a', 'b']); // [[1,3,"a"],[1,3,"b"],[1,4,"a"],[1,4,"b"],[2,3,"a"],[2,3,"b"],[2,4,"a"],[2,4,"b"]] 

我正在尋找一種方式來逆轉這一過程,使得

reverseCartesian(cp,[3,4]); // [[1,'a'],[1,'b'],[2,'a'],[2,'b']] 
+0

[This](http://math.stackexchange.com/q/86322)暗示這是不可能的。你爲什麼要計算這個? –

+0

@MattBall這說,並不是所有的集合都可以分解,但對於那些可以的,你當然可以找到解決方案。 – simonzack

回答

2

我不認爲這將與執行得更快真實的數據,但你可以做這樣的

function reverseCartesian(cp, arr) { 
    return _.chain(cp) 
     .map(_.partial(_.difference, _, arr)) 
     .uniq(function(currentItem) { 
      return currentItem.join("|"); 
     }) 
     .value(); 
} 

console.log(reverseCartesian(cp, [3, 4])); 
// [ [ 1, 'a' ], [ 1, 'b' ], [ 2, 'a' ], [ 2, 'b' ] ] 

注:這是行不通的PR如果數組中有|的元素,則進行適當的操作。仔細選擇這個字符(或一組字符),使它們不會出現在數組中。

+1

非常聰明和美麗,謝謝!我不擔心表現,因爲我的陣列很短。 – Tom