[英]Cartesian product of objects in javascript
我需要根據N個屬性列表生成一組完整的變體,同時保持屬性名稱不變。
var input = [
{ 'colour' : ['red', 'green'] },
{ 'material' : ['cotton', 'wool', 'silk'] },
{ 'shape' : ['round', 'square', 'rectangle'] }
];
var expected = [
{ 'colour': 'red', 'material': 'cotton', 'shape': 'round' },
{ 'colour': 'red', 'material': 'cotton', 'shape': 'square' },
{ 'colour': 'red', 'material': 'cotton', 'shape': 'rectangle' },
{ 'colour': 'red', 'material': 'wool', 'shape': 'round' },
{ 'colour': 'red', 'material': 'wool', 'shape': 'square' },
{ 'colour': 'red', 'material': 'wool', 'shape': 'rectangle' },
{ 'colour': 'red', 'material': 'silk', 'shape': 'round' },
{ 'colour': 'red', 'material': 'silk', 'shape': 'square' },
{ 'colour': 'red', 'material': 'silk', 'shape': 'rectangle' },
{ 'colour': 'green', 'material': 'cotton', 'shape': 'round' },
{ 'colour': 'green', 'material': 'cotton', 'shape': 'square' },
{ 'colour': 'green', 'material': 'cotton', 'shape': 'rectangle' },
{ 'colour': 'green', 'material': 'wool', 'shape': 'round' },
{ 'colour': 'green', 'material': 'wool', 'shape': 'square' },
{ 'colour': 'green', 'material': 'wool', 'shape': 'rectangle' },
{ 'colour': 'green', 'material': 'silk', 'shape': 'round' },
{ 'colour': 'green', 'material': 'silk', 'shape': 'square' },
{ 'colour': 'green', 'material': 'silk', 'shape': 'rectangle' }
];
對於數組的笛卡爾積,有很多算法,但我似乎找不到保留鍵的對象。
性能不是一個大問題,因為每個屬性永遠不會有超過十幾個值。 訂單不必與expected
完全匹配。
我已根據列表的標准算法進行了初步嘗試,但我正在努力:
function cartesianProduct(input, current) {
if (!input || input.length < 1) {
return [];
}
var head = input[0];
var tail = input.slice(1);
var output = [];
for (var key in head) {
for (var i = 0; i < head[key].length; i++) {
if (typeof current == 'undefined') {
var current = {};
}
current[key] = head[key][i];
var productOfTail = cartesianProduct(tail, current);
output.push(current);
console.log(current);
}
}
return output;
}
console.log(cartesianProduct(input));
一旦你擺脫''i'是一個全局變量問題',你可以用這個代碼得到結果:
var input = [
{ 'colour' : ['red', 'green'] },
{ 'material' : ['cotton', 'wool', 'silk'] },
{ 'shape' : ['round', 'square', 'rectangle'] }
];
function cartesianProduct(input, current) {
if (!input || !input.length) { return []; }
var head = input[0];
var tail = input.slice(1);
var output = [];
for (var key in head) {
for (var i = 0; i < head[key].length; i++) {
var newCurrent = copy(current);
newCurrent[key] = head[key][i];
if (tail.length) {
var productOfTail =
cartesianProduct(tail, newCurrent);
output = output.concat(productOfTail);
} else output.push(newCurrent);
}
}
return output;
}
function copy(obj) {
var res = {};
for (var p in obj) res[p] = obj[p];
return res;
}
console.log(cartesianProduct(input));
const input = [ { 'colour': ['red', 'green'] }, { 'material': ['cotton', 'wool', 'silk'] }, { 'shape': ['round', 'square', 'rectangle'] } ] const cartesianProductList = (Xs) => ( R.reduce( (Ys, X) => ( R.map(R.apply(R.append), R.xprod(X, Ys)) ), [[]], Xs ) ) const xPairs = (x, xs) => ( R.map(R.pair(x), xs) ) const cartesianProductObject = (objs) => ( R.pipe( R.mergeAll, R.toPairs, R.map(R.apply(xPairs)), cartesianProductList, R.map(R.fromPairs), )(objs) ) console.log(cartesianProductObject(input))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.