这段代码可以实现你想要的功能:
const arr = [1, 2, 9, 4, 7],
result = Array.from({length: 2 ** (arr.length - 1)}, (_, index) => index.toString(2).padStart(arr.length - 1, "0"))
.map((binary) => JSON.parse("[" + arr.map((num, position) => num + (Number(binary[position]) ? "," : "")).join("") + "]"));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
其结果是:
[
[12947],
[1294, 7],
[129, 47],
[129, 4, 7],
[12, 947],
[12, 94, 7],
[12, 9, 47],
[12, 9, 4, 7],
[1, 2947],
[1, 294, 7],
[1, 29, 47],
[1, 29, 4, 7],
[1, 2, 947],
[1, 2, 94, 7],
[1, 2, 9, 47],
[1, 2, 9, 4, 7]
]
假设预期结果不依赖于顺序,空格表示二进制模式:
12947 => 0000
1294 7 => 0001
129 47 => 0010
…
1 29 47 => 1010
…
1 2 9 4 7 => 1111
我们可以将此模式与计数器一起使用,并将其转换为二进制字符串。我们还用以下内容填充该字符串0
所以它总是保持 4 位数字长:
index.toString(2).padStart(arr.length - 1, "0")
For n digits in arr
, there are exactly 2n - 1 combinations, so we use:
{length: 2 ** (arr.length - 1)}
This is an object that has a length
property of 2arr.length
- 1.
我们将这两件事结合成一个Array.from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from接受两个参数的调用:
用 a 转动物体length
属性到数组中意味着我们创建一个数组length
许多插槽。
映射函数接受槽的索引作为第二个参数。我们只使用索引 — 作为二进制数的计数器。
所以,最后整个表达式:
Array.from({length: 2 ** (arr.length - 1)}, (_, index) => index.toString(2).padStart(arr.length - 1, "0"))
计算结果为以下数组:
[
"0000",
"0001",
"0010",
"0011",
"0100",
"0101",
"0110",
"0111",
"1000",
"1001",
"1010",
"1011",
"1100",
"1101",
"1110",
"1111"
]
我们需要进一步将其映射到最终结果:
.map((binary) => …)
对于每个数组元素,binary
是上面数组中的二进制字符串之一。
为了转动例如"0110"
变成类似的东西"12,9,47"
, 我们需要map
over arr
以及。每个数字num
from arr
后面应该是,
at position
, iff binary
is 1
at position
:
arr.map((num, position) => num + (Number(binary[position]) ? "," : "")).join("")
表达方式(Number(binary[position]) ? "," : "")
评估binary
在指定位置作为数字。如果它是truthy,即除了0
,它评估为","
, 如果它是falsy, i.e. 0
,它评估为""
.
所以中间数组看起来像["1", "2,", "9,", "4", "7"]
。所有这一切都结合在一起"12,9,47"
.
然后,与JSON.parse("[" +
… + "]")
它被当作一个数组来处理和解析,所以它变成了[12, 9, 47]
。由于这些步骤适用于每个二进制字符串,因此您最终将得到最终结果。
-
2 ** (arr.length - 1)
可以替换为Math.pow(2, arr.length - 1)
如果不支持 ECMAScript 7。
-
{length: 2 ** (arr.length - 1)}
可以替换为new Array(2 ** (arr.length - 1))
.
-
(Number(binary[position]) ? "," : "")
可以替换为["", ","][Number(binary[position])]
。在这种情况下,计算出的数字将用作临时数组的索引。