我想在javascript(或算法)中生成多数组中元素的所有排列:
输入:
[
['a', 'b', 'c', 'd'],
['e', 'f', 'g'],
['h', 'i']
]
输出:
[
['a', 'e', 'h'],
['a', 'e', 'i'],
['a', 'f', 'h'],
...
['d', 'g', 'i']
]
注意:我不想要[' a',' b',' c'的排列, ' d''' f',' g',' h',' i& #39;]因为我不想要这样的结果:[' a',' b',' c']。
Note2 :我只对支持N维数组输入的解决方案感兴趣。
谢谢!
答案 0 :(得分:1)
function mutate(array) {
if(array.length === 1)
return array[0].map(el => [el]);
const mutations = mutate(array.slice(1));
const result = [];
for(const el of array[0])
for(const rest of mutations)
result.push([el, ...rest]);
return result;
}
这是一种递归方法。
答案 1 :(得分:1)
如果您喜欢函数式编程,可以在Array类型上使用lift
。就我而言,我为了简单起见使用了RamdaJS:
const input = [
['a', 'b', 'c', 'd'],
['e', 'f', 'g'],
['h', 'i']
]
const output = R.lift ( ( x, y, z ) => [ x, y, z ] ) ( ...input )
console.log( output )
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
这是一个普通的JavaScript lift3
实现:
const input = [
['a', 'b', 'c', 'd'],
['e', 'f', 'g'],
['h', 'i']
]
const flatten = array => [].concat.apply ( [], array )
// Array#flatMap please! ;-)
const ap = funs => array => flatten ( funs.map ( f => array.map ( f ) ) )
const lift3 = f => array1 => array2 => array3 =>
ap ( ap ( array1.map ( f ) ) ( array2 ) ) ( array3 )
const output = lift3 ( x => y => z => [ x, y, z ] ) ( input[0] ) ( input[1] ) ( input[2] )
console.log( output )
答案 2 :(得分:1)
您似乎感兴趣的是套装的笛卡尔积。输出的长度将是集合长度的乘积,我们可以通过以下方法导出任意输出列表中每个元素的列表索引:
// i is the zero-based ouput-list index
// p is the product of input set lengths
function unrank(i, input, p){
let output_list = new Array(input.length);
for (let k=0; k<input.length; k++){
p = Math.floor(p / input[k].length);
let m = Math.floor(i / p);
i = i - m * p;
output_list[k] = input[k][m];
}
return output_list;
}
var input = [
['a', 'b', 'c', 'd'],
['e', 'f', 'g'],
['h', 'i']
];
// Output
var prod = input.map(x => x.length).reduce((a, b) => a * b);
console.log(unrank(23, input, prod));
console.log(unrank(11, input, prod));
要列出所有内容,请将索引从0循环到(输入集长度的乘积 - 1)。
答案 3 :(得分:0)
您可以使用迭代和递归方法。
var d = [['a', 'b', 'c', 'd'], ['e', 'f', 'g'], ['h', 'i']],
processor = array => {
var result = [],
iter = p => p.length < array.length
? array[p.length].forEach(v => iter(p.concat(v)))
: result.push(p);
iter([]);
return result;
};
console.log(processor(d).map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
更短的方法
var d = [['a', 'b', 'c', 'd'], ['e', 'f', 'g'], ['h', 'i']],
result = d.reduce(
(a, b) => a.reduce(
(r, v) => r.concat(b.map(w => [].concat(v, w))),
[]
)
);
console.log(result.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }