Преобразуйте массив двоичных цифр в десятичную с использованием метода array.reduce - PullRequest
2 голосов
/ 10 января 2020

Я пытаюсь использовать array.reduce для массива, представляющего одно двоичное значение. Например, [1,0,1] в двоичном виде преобразует в 5 в десятичном виде.

Я смог успешно преобразовать двоичное и десятичное, используя некоторое время l oop, но хотел бы обновить мой код, чтобы использовать метод 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)

Это был мой код, использующий время l oop

    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

Ответы [ 2 ]

4 голосов
/ 10 января 2020

Вы можете уменьшить массив, умножить последнее значение и добавить фактическое значение.

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)
1 голос
/ 11 января 2020

Проблема в том, что вы изменяете массив, так как reduce перебирает его. Это меняет массив под ним, поэтому операция не совпадает с c базовыми значениями. Вот (несколько небрежно) иллюстрация того, как 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)
...