【问题标题】:Convet array of binary digits to a decimal using array.reduce method使用 array.reduce 方法将二进制数字数组转换为十进制
【发布时间】:2020-04-28 12:18:49
【问题描述】:

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

【问题讨论】:

  • 您在迭代数组时正在对其进行变异。只是......不要那样做,因为在你转移出指数后,你会让整个操作出错。
  • 我希望这里提出的所有问题都在范围内如此清晰,并带有自己的测试。为此 +1!

标签: javascript arrays binary reduce


【解决方案1】:

您可以减少数组并乘以最后一个值并添加实际值。

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)

【讨论】:

    【解决方案2】:

    问题是你正在改变数组,因为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(因为索引是从 0 开始的,而长度 = 1 只有索引 = 0),然后减去正常索引。这为您提供了每个值所代表的两个的幂:

    //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)

    【讨论】:

    • 谢谢,在我最初的尝试中,我非常接近您的建议。我很欣赏清晰简洁的解释
    【解决方案3】:

    我发现使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-08
      • 2020-04-28
      • 2011-01-08
      • 2010-12-08
      • 2016-12-25
      • 2012-06-12
      • 1970-01-01
      • 2019-12-14
      相关资源
      最近更新 更多