我正在尝试查找2个数组的每个排列,如下所示:
// input
lowerWords = ['one', 'two', 'three' ]
upperWords = [ 'ONE', 'TWO', 'THREE' ]
// output
keywords = {
'one two three': true,
'ONE two three': true,
'ONE TWO three': true,
'ONE TWO THREE': true,
'ONE two THREE': true,
'one TWO three': true,
'one two THREE': true,
'one TWO THREE': true,
}
它应该与3个以上的项目一起工作,两个数组的长度始终相同。这是我的代码:
const keywords = {}
const lowerWords = ['one', 'two', 'three' ]
const upperWords = [ 'ONE', 'TWO', 'THREE' ]
const wordCount = lowerWords.length
let currentWord = 0
let currentWords = [...upperWords]
while (currentWord < wordCount) {
currentWords[currentWord] = lowerWords[currentWord]
let keyword = currentWords.join(' ')
keywords[keyword] = true
currentWord++
}
currentWord = 0
currentWords = [...lowerWords]
while (currentWord < wordCount) {
currentWords[currentWord] = upperWords[currentWord]
let keyword = currentWords.join(' ')
keywords[keyword] = true
currentWord++
}
结果缺少一些
ONE TWO THREE: true
ONE TWO three: true
ONE two three: true
one TWO THREE: true
one two THREE: true
one two three: true
答案 0 :(得分:9)
您可以转置数组以获取对数组,然后获取对的所有组合。
const
transpose = array => array.reduce((r, a) => a.map((v, i) => [...(r[i] || []), v]), []),
combinations = array => array.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));
var lowerWords = ['one', 'two', 'three'],
upperWords = ['ONE', 'TWO', 'THREE'],
pairs = transpose([lowerWords, upperWords]),
result = combinations(pairs);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
我想尝试一下。我使用二进制文件来获得可能的组合,因为此问题需要以2为基础的解决方案:
const low = ["one", "two", "three"];
const up = ["ONE", "TWO", "THREE"];
const words = [low, up]
const len = words[0].length
function getCombinations(noOfArrays, len) {
var temp, newCombo, combos = [];
for (var i = 0; i < (noOfArrays ** len); i++) {
temp = new Array(len).fill(0)
newCombo = i.toString(noOfArrays).split('');
newCombo.forEach((el, i) => temp[temp.length - newCombo.length + i] = +el);
combos.push(temp);
}
return combos;
}
function setCombinations(combos) {
return combos.map(combo => combo.map((el, i) => words[el][i]))
}
var combos = getCombinations(words.length, len)
combos = setCombinations(combos)
console.log(combos)
循环说明:
1. temp = new Array(len).fill(0)
2. newCombo = i.toString(2).split("");
3. newCombo.forEach((el, i) => temp[temp.length - newCombo.length + i] = +el);
[0,0,0]
1 -> 1
2 -> 10
3 -> 11
4 -> 100
etc...
然后将二进制文件拆分为数组100 -> [1,0,0]
。
10 -> [1,0]
)推入数组的后面带来了问题。我用temp.length - newCombo.length + i
来解决这个问题。然后该函数返回:
[ 0, 0, 0 ]
[ 0, 0, 1 ]
[ 0, 1, 0 ]
[ 0, 1, 1 ]
[ 1, 0, 0 ]
[ 1, 0, 1 ]
[ 1, 1, 0 ]
[ 1, 1, 1 ]
然后,我可以映射每个组合,并根据值获取每个数组,并通过循环索引获取单词(“ one”或“ ONE”)。
请注意,此代码可用于多个数组,只要数组的长度都相同。
答案 2 :(得分:1)
我们可以直接列举这些。这可能是您了解递归的好机会。该算法非常简单:
If we've reached the end of
the list, return the combination
the current recursion branch is
building.
Otherwise, create a new branch
that picks the next item from B,
while the current branch picks
the next item from A.
JavaScript代码:
function f(A, B, i=0, comb=[]){
return i == A.length
? [comb]
: f(A, B, i + 1, comb.concat(A[i])).concat(
f(A, B, i + 1, comb.slice().concat(B[i])))
}
console.log(JSON.stringify(f(['one','two','three'], ['ONE','TWO','THREE'])))
答案 3 :(得分:1)
您总共需要获得2 ^ 3个组合。如果您从2个数组中创建2D矩阵,则下表代表应从中获取该项的行号。
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
如果分析组合的索引,则每个组合都是从0到2 ^ 3的二进制数,前导零。
所以,您可以
toString(2)
padStart
split
每个数字获取一个数组matrix[digit-from-binary][position-of-each-split]
join
带有' '
分隔符的项目数组,以获取 key
function getAllCombinations(matrix) {
const combinations = 2 ** 3,
output = {};
for(let i = 0; i < combinations; i++) {
const key = i.toString(2)
.padStart(3, 0)
.split('')
.map((n, j) => matrix[n][j])
.join(" ")
output[key] = true;
}
return output
}
console.log(getAllCombinations([['one', 'two', 'three' ],[ 'ONE', 'TWO', 'THREE' ]]))
您可以将其概括为m x n
矩阵。您无需将其分别转换为二进制数,而需要将其转换为base-m
并将padStart
转换为长度n
function getAllCombinations(matrix) {
const rows = matrix.length,
columns = matrix[0].length,
combinations = rows ** columns,
output = {}
for(let i = 0; i < combinations; i++) {
const key = i.toString(rows)
.padStart(columns, 0)
.split('')
.map((n, j) => matrix[n][j])
.join(" ")
output[key] = true;
}
return output
}
console.log(getAllCombinations([[1, 2, 3 ],[ 4, 5, 6], [ 7, 8, 9]])) // 3 x 3 matrix
console.log(getAllCombinations([[1, 2], [3, 4], [5, 6], [7, 8]])) // 4 x 2 matrix
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 4 :(得分:0)
以下代码应为您提供递归方法:
const sidebarOpen = 'SIDEBAR_OPEN';
const initialState = { show: false }
export const actionCreators = {
open: () => ({
type: sidebarOpen
})
};
export const reducer = (state, action) => {
state = state || initialState;
console.log("Initial State");
console.log(state)
if (action.type === sidebarOpen) {
return {
...state,
show: state.show = true
};
} else {
return {
...state,
show: state.show = false
}
}
return state;
};
答案 5 :(得分:0)
这是基于我的其他answer的通用版本,该版本处理可变长度的可变数量的输入数组:
const g = (arrs, i=0, comb=[]) =>
!arrs.some(arr => i < arr.length)
? [comb]
: arrs.reduce((acc, arr) =>
i >= arr.length ? acc :
acc.concat(g(arrs, i + 1, comb.slice().concat(arr[i])))
, [])
// Example output
let input = [['ONE','TWO','THREE'], ['one','two'], [1,2,3,4]]
let str = ''
for (let line of g(input))
str += JSON.stringify(line) + '\n'
console.log(str)