Javascript对象或数组的排列组合
Permutation and combination of Javascript Object or Array
我有一个这样的 javascript 对象:
[{"w": 202, "h": 302}, { "w": 402, "h": 502}, {"w": 802, "h": 702}]
我想用所有可能的组合生成它:
{
[{"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}]
}
是的,这个答案是 this earlier post on generating a Cartesian product from arrays 的应用,因此可以看作是重复的。但也许实际的实现仍然在这里增加了一些价值:
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)));
通用解决方案需要嵌套在笛卡尔积中的排列,该排列允许具有不同 属性 counts/names 的对象。这里使用 Permutations in JavaScript? and Cartesian product of multiple arrays in JavaScript 的答案,然后将结果映射到原始输入的 Object.keys
。
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
*/
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
*/
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>
具有不同 属性 计数的示例
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
*/
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
*/
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>
我有一个这样的 javascript 对象:
[{"w": 202, "h": 302}, { "w": 402, "h": 502}, {"w": 802, "h": 702}]
我想用所有可能的组合生成它:
{
[{"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}]
}
是的,这个答案是 this earlier post on generating a Cartesian product from arrays 的应用,因此可以看作是重复的。但也许实际的实现仍然在这里增加了一些价值:
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)));
通用解决方案需要嵌套在笛卡尔积中的排列,该排列允许具有不同 属性 counts/names 的对象。这里使用 Permutations in JavaScript? and Cartesian product of multiple arrays in JavaScript 的答案,然后将结果映射到原始输入的 Object.keys
。
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
*/
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
*/
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>
具有不同 属性 计数的示例
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
*/
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
*/
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>