为什么拒绝不是拒绝?

Why is reject not rejecting?

此代码在 Exercism.io 上的汉明距离问题上是 my initial stab,但是当字符串 a 长于字符串 b 时它失败了,我'我想知道为什么。

def self.compute(a, b)
  a.split('').reject.with_index { |c, i| c == b[i] }.size
end

我通过修剪第一个字符串解决了这个问题...

def self.compute(a, b)
  a[0...b.size].split('').reject.with_index { |c, i| c == b[i] }.size
end

...但我不明白为什么 reject 包含额外的字符。当我检查比较结果时,它们似乎是错误的,正如我所预料的那样,但仍包含在结果中。

谁能告诉我为什么?

这是另一种涉及大量排序的方法,可能不是最优的,但可以作为更有效解决方案的基础:

def ham(a,b)
  [ a.length, b.length ].sort[1].times.reject do |i|
    a[i] != b[i]
  end.sort[-1]
end

pairs = [
  ['A', 'A'],
  ['A','G'],
  ['AG','CT'],
  ['AT','CT'],
  ['GGACG', 'GGTCG'],
  ['AGAGACTTA', 'AAA'],
  ['AGG', 'AAAACTGACCCACCCCAGG'],
  ['GATACA', 'GCATAA'],
  ['GGACGGATTCTG', 'AGGACGGATTCT']
]

pairs.each do |pair|
  puts '%s -> %s' % [ pair.inspect, ham(*pair).inspect ]
end

# ["A", "A"] -> 0
# ["A", "G"] -> nil
# ["AG", "CT"] -> nil
# ["AT", "CT"] -> 1
# ["GGACG", "GGTCG"] -> 4
# ["AGAGACTTA", "AAA"] -> 2
# ["AGG", "AAAACTGACCCACCCCAGG"] -> 0
# ["GATACA", "GCATAA"] -> 5
# ["GGACGGATTCTG", "AGGACGGATTCT"] -> 8

在您的版本中,如果长度不同,您似乎没有比较最长的字符串和最短的字符串。按长度排序解决了这个问题。

I don't understand why reject is including the extra characters. When I check the comparisons, they seem to be coming up false

正确。当您拒绝时,false 表示 "accept" - 与拒绝相反。

问题只是您没有理解 "reject" 的含义。当你遇到这样的问题时,debug。在这种情况下,这样做的方法是消除多余的 material 并专注于让您感到困惑的事情。去掉size调用,只看reject调用的结果:

def compute(a, b)
  a.split('').reject.with_index { |c, i| c == b[i] }
end
result = compute("hey", "ha")
puts result

输出为"e""y"。这是有道理的:

  • 在第一次通过时,"h" == "h" 被拒绝了。

  • 第二遍,"e" != "a" 被接受。

  • 第三遍,"y"没有可比性,无法成功;因此我们无法 拒绝 — 因此 "y" 被接受。这就是你问的。