如何使用Array#reduce以这种方式工作?

时间:2016-11-26 23:18:25

标签: ruby reduce inject

过去几周我一直在学习ruby,我遇到过类似的事情:

array = [10, 20, 20];

array.reduce(:^)

# => 10

评估为10。

代码的目的是在[10, 20, 20]之类的序列中找到一个奇数出现的元素。

有没有人对这如何运作有一个相对简单的解释?

3 个答案:

答案 0 :(得分:6)

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#^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

答案 1 :(得分:2)

reduce通过应用二进制操作组合Enumerable的所有元素。 ^是按位异或(XOR)运算符。

array.reduce(:^)执行array元素的按位异或。对于array = [10, 20, 20],这会执行(10 ^ 20) ^ 20,结果为10

数字的按位异或本身为0且XOR是关联的(顺序并不重要)。因此,数组中的每对相同数字都被抵消,使得任何数字的XOR出现奇数次。如果数组中有一个数字出现奇数次,那么这个数字就是结果。

答案 2 :(得分:0)

Fixnum#^按位异或()运算符(XOR)。

(10 ^ 20) ^ 20 #=> 10

我不确定您如何使用奇数次数过滤数字。