我试图使用朴素的for-loop方法计算数组中提供的数字的二进制数。 比我找到一个有效的解决方案,但我无法理解它是如何工作的。 我需要帮助才能理解这一点。
const binaryArrayToNumber = arr => {
return arr.reduce((a,b)=>(a<<1|b),0);
};
console.log(binaryArrayToNumber([1,1,1,1]))
答案 0 :(得分:0)
reduce函数用作累加器。 (a,b)对实际上是(total,currentValue)。例如,如果要计算总和为1,2和3,则可以使用以下代码:
var sum = [1, 2, 3].reduce(
function(total, currentNumber){ return total + currentNumber; }
, 0);
对于每次迭代, currentNumber 的 total 变量的值都会增加,并且在迭代完所有数组元素之后, total 被分配给 sum 变量。
匿名函数的第二个参数(在本例中为0)是sum的初始值(在迭代数组元素之前)。
因此,上面的代码与此代码相同:
var sum = 0;
for (var i = 1; i <=3; i++)
{
sum = sum + i;
}
答案 1 :(得分:0)
<<
left logical shift)将数字向左移动。如果数字n
为00010110
则为:
n << 1
将为00101100
。n << 2
将为01011000
。运算符|
(betwise or)对相同位置的位执行iclusive逻辑OR。如果数字n
和m
分别为00110100
和10010101
,则:
n = 00110100
m = 10010101
----------------
n | m = 10110101
遵循以下规则:0 | 0 = 0
,0 | 1 = 1
,1 | 0 = 1
和1 | 1 = 1
。
现在reduce部分:reduce
遍历数组,将累加器(最初由用户设置,最后一个参数)和数组的当前项传递给回调(函数)作为第一个参数传递)并将累加器的值设置为该回调的返回值。
因此,对于数组中的每个项目,我们将累加器向左移动以为新位创建一个位置,然后使用betwise或者将位添加到该位置。这是一个解释的例子:
var arr = [1, 0, 1];
reduce
将以等于0的累加器开始(...,0);
行末尾为reduce
),然后将其与当前项(第一项)一起传递给回调。回调会将accumulataror(a
)向左移动1:首先移动累加器:
a = 00000000;
a << 1 = 00000000;
然后使用数组a
中的当前项返回向后的b
的结果或结果:
b = 00000001;
00000000 | b = 00000001;
现在新累加器是上述代码(00000001
)的结果。
reduce
然后将当前累加器与数组中的当前项(现在是第二个)一起传递给回调:首先:
a = 00000001;
a << 1 = 00000010;
和
b = 00000000;
00000010 | b = 00000010;
首先:
a = 00000010;
a << 1 = 00000100;
和
b = 00000001;
00000100 | 00000001 = 00000101;
reduce
将返回累计值(最后一次调用回调的累加器返回即 a
)结果如果您不清楚语法return arr.reduce((a,b)=>(a<<1|b),0);
,那是因为您不熟悉Arrow functions。确切的行可以使用这样的常规函数编写:
return arr.reduce(function(a, b) { // a the accumulator, b the curent item from the array
return (a << 1) | b; // return something to store as the new accumulator
}, 0; // 0 is the initial value of the accumulator
不使用任何二元操作,也不使用reduce
:
var arr = [1, 0, 1, 1];
var number = parseInt(arr.join(''), 2);
console.log(number);
arr.join('')
将返回一个字符串(数组"1011"
中所有项的串联)。然后parseInt
将该字符串解析为二进制数。