使用array.reduce方法将二进制数字数组转换为十进制



我正在尝试在表示单个二进制值的数组上使用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

最新更新