我正在尝试在表示单个二进制值的数组上使用array.reduce。例如,二进制中的 [1,0,1] 将转换为十进制中的 5。
我已经能够使用 while 循环在二进制和十进制之间成功转换,但想升级我的代码以使用 reduce 方法。
到目前为止,我实现的在数组中最多可以精确到 6 个元素。我不确定为什么,但是在 6 次挖掘后,转换失败。
此外,我正在使用公式进行转换。例如:要将111001转换为十进制,您必须执行 (1*2^5
( + (1*2^4( (1*2^3( + (0*2^2( + (0*2^1( + (1*2^0(。
const getDecimalValue = function (head) {
let total = head.reduce(
(sum) =>
sum + (head.shift() * Math.pow(2, head.length))
)
return total
}
console.log(getDecimalValue([1, 0, 1]) == 5)
console.log(getDecimalValue([1, 1, 1, 0, 0, 1]) == 57)
console.log(getDecimalValue([1, 1, 1, 0, 0, 1, 1]) == 115)
console.log(getDecimalValue([0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0]) == 7392)
console.log(getDecimalValue([1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]) == 18880)
这是我使用 while 循环的代码
let sum = 0
while ((i = head.shift()) !== undefined) {
sum += (i * Math.pow(2, head.length))
console.log(i * Math.pow(2, head.length))
}
return sum
您可以缩小数组并将最后一个值相乘并添加实际值。
const getDecimalValue = array => array.reduce((r, v) => r * 2 + v, 0);
console.log(getDecimalValue([1, 0, 1]) == 5)
console.log(getDecimalValue([1, 1, 1, 0, 0, 1]) == 57)
console.log(getDecimalValue([1, 1, 1, 0, 0, 1, 1]) == 115)
console.log(getDecimalValue([0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0]) == 7392)
console.log(getDecimalValue([1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]) == 18880)
问题是你在迭代数组时reduce
正在改变数组。这会更改下面的数组,因此操作与基础值不同步。下面是一个(有点松散的(reduce
通常如何遍历数组的图示:
arr = [1, 2, 3]
^ ^ ^
| | |
iteration 1 -- | |
iteration 2 ----- |
iteration 3 --------
以下是每次迭代修改它时发生的情况:
//start
arr = [1, 2, 3]
//at iteration 1
[2, 3] _
^
|
iteration 1 --
//at iteration 2
[3] _ _
^
|
iteration 2 -----
//at iteration 3
[] _ _
^
|
iteration 3 ------
相反,获得功能的直接方法是使每个项目为 2 的幂,等于项目的反向索引
//index: 0 1 2 3
arr = [1, 0, 1, 0]
//reverse index: 3 2 1 0
方便的是,要获得它,您只需从数组长度中减去1
(因为 indeces 是从 0 开始的,长度 = 1 只有索引 = 0(,然后减去正常索引。这为您提供了每个值表示的 2 的幂:
//reverse index: 3 2 1 0
arr = [1, 0, 1, 0]
//power of 2: 8 4 2 1
//multiply and sum: 8 + 0 + 2 + 0 = 10
这是使用reduce
的代码:
const getDecimalValue = function (head) {
let total = head.reduce(
(sum, item, index, array) =>
sum + item * Math.pow(2, (array.length - index - 1)),
// reverse index ^^^^^^^^^^^^^^^^^^^^^^^^
0
)
return total
}
console.log(getDecimalValue([1, 0, 1]) == 5)
console.log(getDecimalValue([1, 1, 1, 0, 0, 1]) == 57)
console.log(getDecimalValue([1, 1, 1, 0, 0, 1, 1]) == 115)
console.log(getDecimalValue([0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0]) == 7392)
console.log(getDecimalValue([1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]) == 18880)
我发现使用以下函数和Array.prototype.reduceRight((更具可读性。
function binaryToDecimal(arr) {
let decimal = 0;
arr.reduceRight((base, binaryNum) => {
if (binaryNum === 1) {
decimal += base;
}
base = base * 2;
return base;
}, 1);
return decimal;
}
binaryToDecimal([1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0])===3462