以这种方式使用 Array#reduce 如何工作?
How does using Array#reduce in this way work?
过去几周我一直在学习 ruby,我遇到了类似这样的事情:
array = [10, 20, 20];
array.reduce(:^)
# => 10
评估为 10。
该代码的目的是在 [10, 20, 20]
.
等序列中查找出现次数为奇数的元素
有没有人对它的工作原理有一个相对简单的解释?
Fixnum#^
是 按位异或 运算符 (XOR)。
(10 ^ 20) ^ 20 #=> 10
不过,我不确定您如何过滤出现次数为奇数的数字。
reduce
combines all the elements of an Enumerable
by applying a binary operation. ^
是按位异或 (XOR) 运算符。
array.reduce(:^)
对 array
的元素执行按位异或。对于 array = [10, 20, 20]
,执行 (10 ^ 20) ^ 20
,给出结果 10
。
一个数和它本身的按位异或为0并且异或是关联的(顺序不重要)。因此,数组中的每一对相同数字都被抵消,留下出现奇数次的任何数字的异或。如果数组中有一个数字出现奇数次,那么这个数字就是结果。
array = [10, 20, 20];
array.reduce(:^)
#=> 10
产生与
相同的结果
array.reduce { |t,n| t^n }
#=> 10
让我们添加一个 puts
语句看看发生了什么。
array.reduce do |t,n|
puts "t = #{t}, n = #{n}, t^n = #{t^n}"
t^n
end
# t = 10, n = 20, t^n = 30
# t = 30, n = 20, t^n = 10
#=> 10
当 Enumerable#reduce 没有给出参数时,"memo"(块变量t
)被设置为等于接收者的第一个元素(10
)和传递给块的第一个元素是接收器的第二个元素,20
.
Fixnum#^ is the bitwise "exclusive-or" 运算符 (XOR).
当t #=> 10
和(第一个)n #=> 20
被传递到区块时:
t^n #=> 30
因为
10.to_s(2) #=> "01010"
20.to_s(2) #=> "10100"
-----
(10^20).to_s(2) #=> "11110"
"11110".to_i(2) #=> 30
10^20 #=> 30
当t #=> 30
和(第二个)n #=> 20
被传递到区块时:
t^n #=> 10
因为
30.to_s(2) #=> "11110"
20.to_s(2) #=> "10100"
-----
(30^20).to_s(2) #=> "01010"
"1010".to_i(2) #=> 10
(30^20) #=> 10
过去几周我一直在学习 ruby,我遇到了类似这样的事情:
array = [10, 20, 20];
array.reduce(:^)
# => 10
评估为 10。
该代码的目的是在 [10, 20, 20]
.
有没有人对它的工作原理有一个相对简单的解释?
Fixnum#^
是 按位异或 运算符 (XOR)。
(10 ^ 20) ^ 20 #=> 10
不过,我不确定您如何过滤出现次数为奇数的数字。
reduce
combines all the elements of an Enumerable
by applying a binary operation. ^
是按位异或 (XOR) 运算符。
array.reduce(:^)
对 array
的元素执行按位异或。对于 array = [10, 20, 20]
,执行 (10 ^ 20) ^ 20
,给出结果 10
。
一个数和它本身的按位异或为0并且异或是关联的(顺序不重要)。因此,数组中的每一对相同数字都被抵消,留下出现奇数次的任何数字的异或。如果数组中有一个数字出现奇数次,那么这个数字就是结果。
array = [10, 20, 20];
array.reduce(:^)
#=> 10
产生与
相同的结果array.reduce { |t,n| t^n }
#=> 10
让我们添加一个 puts
语句看看发生了什么。
array.reduce do |t,n|
puts "t = #{t}, n = #{n}, t^n = #{t^n}"
t^n
end
# t = 10, n = 20, t^n = 30
# t = 30, n = 20, t^n = 10
#=> 10
当 Enumerable#reduce 没有给出参数时,"memo"(块变量t
)被设置为等于接收者的第一个元素(10
)和传递给块的第一个元素是接收器的第二个元素,20
.
Fixnum#^ is the bitwise "exclusive-or" 运算符 (XOR).
当t #=> 10
和(第一个)n #=> 20
被传递到区块时:
t^n #=> 30
因为
10.to_s(2) #=> "01010"
20.to_s(2) #=> "10100"
-----
(10^20).to_s(2) #=> "11110"
"11110".to_i(2) #=> 30
10^20 #=> 30
当t #=> 30
和(第二个)n #=> 20
被传递到区块时:
t^n #=> 10
因为
30.to_s(2) #=> "11110"
20.to_s(2) #=> "10100"
-----
(30^20).to_s(2) #=> "01010"
"1010".to_i(2) #=> 10
(30^20) #=> 10