JS 中的递归挑战将所有可能的数组键组合为 true |错误版本,我附上输入和输出
Posted
技术标签:
【中文标题】JS 中的递归挑战将所有可能的数组键组合为 true |错误版本,我附上输入和输出【英文标题】:Recursive challenge in JS combining all possible array keys in true | false versions, I attach the input and output 【发布时间】:2020-09-18 17:27:00 【问题描述】:我找到了很多关于数组值之间所有可能组合的解决方案,但我需要一些不同的东西,希望你能支持我。基本上是创建所有可能的对象,将数组键与 true|false 值组合在一起,如下所示:
输入:(应该返回一个由 32 个对象组成的数组,2exp5,5 个键中的两个可能值)
let properties = ['arm','lens','season','food','size'];
输出:
let combinations = [
"arm": "false","lens": "false","season": "false","food": "false","size": "false"
"arm": "false","lens": "false","season": "false","food": "false","size": "true"
"arm": "false","lens": "false","season": "false","food": "true","size": "true"
"arm": "false","lens": "false","season": "true","food": "true","size": "true"
"arm": "false","lens": "true","season": "true","food": "true","size": "true"
"arm": "true","lens": "true","season": "true","food": "true","size": "true"
"arm": "true","lens": "true","season": "true","food": "false","size": "true"
"arm": "true","lens": "true","season": "false","food": "false","size": "true"
and so on...
]
非常感谢!
【问题讨论】:
你尝试了什么? 这不是javascript,但我阅读了这些线程以获取逻辑***.com/questions/5162254/…。 @adiga 已经解决了我的问题。谢谢! 【参考方案1】:您可以为每个属性使用带有开关的二维矩阵。然后为每个键创建条目并使用Object.fromEntries()
创建对象
0 0 0 0 0
0 0 0 0 1
0 0 0 1 0
0 0 0 1 1
etc
数组中总共需要2 ** keys.length
个对象。所以,使用Array.from( 2 ** keys.length )
创建它
在map函数中,使用row.toString(2)
为当前行创建一个二进制数
添加前导 0 直到字符串为 keys.length
long: ("00001"
)
拆分字符串使其成为一个数组 (["0", "0", "0", "0", "1"]
)
映射这个数组并为对应的键创建一个条目数组
[["arm","false"],["lens","false"],["season","false"],["food","false"],["size","false"]]
使用Object.fromEntries()
从条目数组创建一个对象
这是一个sn-p:
let keys = ['arm', 'lens', 'season', 'food', 'size'];
function combination(keys)
return Array.from( length: 2 ** keys.length , (_, row) =>
Object.fromEntries(
row.toString(2)
.padStart(keys.length, 0)
.split('')
.map((binary, j) => [keys[j], String(Boolean(+binary))])
)
)
console.log(combination(keys))
【讨论】:
你成功了兄弟!你能推荐我学习任何主题或课程,以便能够自己解决这些问题吗?我习惯于从 ws 传统的前端请求数据,但我想提高我解决逻辑问题的技能。非常感谢!【参考方案2】:我们可以在两个可重用的函数上构建它,如下所示:
const crossproduct = (xss) =>
xss.reduce ((ps, xs) => ps.reduce ((r, p) => [...r, ...(xs.map (x => [...p, x]))], []), [[]])
const mergeAll = xs =>
Object.assign (, ...xs)
const combine = (properties, values) =>
crossproduct (properties.map (p => values.map (v => ([p]: v))))
.map (mergeAll)
const properties = ['arm', 'lens', 'season', 'food', 'size']
const values = [true, false]
console.log (combine (properties, values))
.as-console-wrapper min-height: 100% !important; top: 0
我们的实用功能是:
crossproduct
,它接受一个数组数组并找到它们的笛卡尔积。例如,
crossproduct ([['a', 'b', 'c'], [1, 2], ['x', 'y']])
//=> [["a", 1, "x"], ["a", 1, "y"], ["a", 2, "x"], ["a", 2, "y"],
// ["b", 1, "x"], ["b", 1, "y"], ["b", 2, "x"], ["b", 2, "y"],
// ["c", 1, "x"], ["c", 1, "y"], ["c", 2, "x"], ["c", 2, "y"]]
和 mergeAll
,它将一组单独的对象组合成一个,如下所示:
mergeAll ([foo: 1, bar: 2, baz: 3])
//=> foo: 1, bar: 2, baz: 3
这只是Object.assign
的一个薄包装,只需将其应用于数组而不是单个对象。
我们的主要函数combine
首先创建一个数组数组,将各个属性名称与如下值匹配:
[
["arm": true, "arm": false],
["lens": true, "lens": false],
["season": true, "season": false],
["food": true, "food": false],
["size": true, "size": false]
]
这是位properties.map (p => values.map (v => ([p]: v)))
。虽然可以将其提取为独立函数,但它似乎没有任何其他用途,因此决定只是代码美学问题。
我们在这个结果上调用crossproduct
,得到这个中间格式:
[
["arm": true, "lens": true, "season": true, "food": true, "size": true],
["arm": true, "lens": true, "season": true, "food": true, "size": false],
["arm": true, "lens": true, "season": true, "food": false, "size": true],
["arm": true, "lens": true, "season": true, "food": false, "size": false],
// ...
["arm": false, "lens": false, "season": false, "food": false, "size": false]
]
最后,我们在该数组上调用 .map (mergeAll)
以获得我们的最终格式。
注意,如果mergeAll
真的没有其他用途,它很短,可以很容易地在主函数中内联为.map (xs => Object.assign (, ...xs))
。这是我经常使用的一个功能,并且可以在我的实用工具箱中派上用场,所以我个人不会内联它。你可能会有不同的感觉。
请注意这里的基本思想。我们不会尝试一次性解决问题,而是应用一系列转换来获得最终格式。这使我们可以在其中一些步骤中利用可重用的功能。这是一种强大的技术。
【讨论】:
暂时没有过路。令人愉快的分解导致完全可重复使用的部分。这让我想起了构建truth table 所需的许多步骤。我有一个模块,也许我会添加一个作为有趣的答案 非常好的答案和理由,非常感谢!【参考方案3】:从空数组开始构建,并为键添加 2 种可能性(真/假)。 通过遍历所有键来重复该过程,对于每个键,都取之前的可用结果。
let properties = ["arm", "lens", "season", "food", "size"];
const addTwo = (arr, key) =>
const result = [];
["true", "false"].forEach((val) =>
arr.forEach((item) => result.push( ...item, [key]: val ))
);
return result;
;
const combinations = (arr) =>
let output = [];
arr.forEach((key) => (output = addTwo(output, key)));
return output;
;
console.log(combinations(properties));
【讨论】:
清晰整洁!非常感谢!以上是关于JS 中的递归挑战将所有可能的数组键组合为 true |错误版本,我附上输入和输出的主要内容,如果未能解决你的问题,请参考以下文章
leecode---40---数组,dfs---求所有的组合为target,有重复数组