I have a javascript object like this:
[{"w": 202, "h": 302}, { "w": 402, "h": 502}, {"w": 802, "h": 702}]
and I want to generate it like this with all the possible combination:
{
[{"w": 302, "h": 202}, { "w": 402, "h": 502}, {"w": 802, "h": 702}],
[{"w": 202, "h": 302}, { "w": 502, "h": 402}, {"w": 802, "h": 702}],
[{"w": 202, "h": 302}, { "w": 402, "h": 502}, {"w": 702, "h": 802}],
[{"w": 302, "h": 202}, { "w": 502, "h": 402}, {"w": 802, "h": 702}],
[{"w": 202, "h": 302}, { "w": 502, "h": 402}, {"w": 702, "h": 802}],
[{"w": 302, "h": 202}, { "w": 402, "h": 502}, {"w": 702, "h": 802}],
[{"w": 302, "h": 202}, { "w": 502, "h": 402}, {"w": 702, "h": 802}]
}
CodePudding user response:
Yes, this answer is an application of this earlier post on generating a Cartesian product from arrays and can therefore be seen as a duplicate. But maybe the actual implementation still adds some value here:
const da=[{"w": 202, "h": 302}, { "w": 402, "h": 502}, {"w": 802, "h": 702}];
function cart(da){
const arr=da.map(o=>[o,{w:o.h,h:o.w}]);
return arr.reduce((a0, a) => a0.flatMap(e0 => a.map(e => [e0, e].flat())))
}
console.log(JSON.stringify(cart(da)));
CodePudding user response:
A generic solution requires a permutation nested in a cartesian product which allows for objects with varying property counts/names. Here using answers from Permutations in JavaScript? and Cartesian product of multiple arrays in JavaScript and them mapping the result against the Object.keys
of the original input.
const input = [{ "w": 202, "h": 302 }, { "w": 402, "h": 502 }, { "w": 802, "h": 702 }];
const result = cartesian(
...input.map(o =>
permute(Object.values(o))
.map(v => [v])
))
.map(vs =>
vs.map((v, i) =>
Object.fromEntries(
Object.keys(input[i]).map((k, j) => [k, v[j]]))
)
);
// log
result.forEach(r => console.log(JSON.stringify(r)));
<script>
/**
* @see https://stackoverflow.com/questions/9960908/permutations-in-javascript
*/
function permute(permutation) {
var length = permutation.length,
result = [permutation.slice()],
c = new Array(length).fill(0),
i = 1, k, p;
while (i < length) {
if (c[i] < i) {
k = i % 2 && c[i];
p = permutation[i];
permutation[i] = permutation[k];
permutation[k] = p;
c[i];
i = 1;
result.push(permutation.slice());
} else {
c[i] = 0;
i;
}
}
return result;
}
/**
* @see https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript
*/
let f = (a, b) => [].concat(...a.map(a => b.map(b => [].concat(a, b))));
let cartesian = (a, b, ...c) => b ? cartesian(f(a, b), ...c) : a;
</script>
Example with varying property counts
const input = [{ "w": 202}, { "w": 402, "h": 502, "x": 'extra prop' }, { "w": 802, "h": 702 }];
const result = cartesian(
...input.map(o => permute(Object.values(o)).map(v => [v])))
.map(vs => vs.map((v, i) =>
Object.fromEntries(
Object.keys(input[i]).map((k, j) => [k, v[j]]))));
// log
result.forEach(r => console.log(JSON.stringify(r)));
<script>
/**
* @see https://stackoverflow.com/questions/9960908/permutations-in-javascript
*/
function permute(permutation) {
var length = permutation.length,
result = [permutation.slice()],
c = new Array(length).fill(0),
i = 1, k, p;
while (i < length) {
if (c[i] < i) {
k = i % 2 && c[i];
p = permutation[i];
permutation[i] = permutation[k];
permutation[k] = p;
c[i];
i = 1;
result.push(permutation.slice());
} else {
c[i] = 0;
i;
}
}
return result;
}
/**
* @see https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript
*/
let f = (a, b) => [].concat(...a.map(a => b.map(b => [].concat(a, b))));
let cartesian = (a, b, ...c) => b ? cartesian(f(a, b), ...c) : a;
</script>