比较哈希与红宝石中的字符串

时间:2020-02-03 19:47:49

标签: ruby string hash

我正在尝试做类似字符串分析器的事情,我需要检索单词的结尾并将其与哈希键进行比较

word = "Test"
ending_hash = {"e" => 1, "st" => 2}
output = 2

在这种情况下,我需要输出为2,但实际上我不知道结尾的长度是1个字符还是2个字符。有可能吗?

2 个答案:

答案 0 :(得分:2)

最初,假设您知道word以(至少)个键ending_hash结尾。然后,您可以编写:

word = "Test"
ending_hash = {"e" => 1, "st" => 2}

ending_hash.find { |k,v| word.end_with?(k) }.last
  #=> 2

请参见Enumerable#findString#end_with?Array#last

中间计算如下:

ending_hash.find { |k,v| word.end_with?(k) }
  #=> ["st", 2]

如果不确定任何键是否与字符串的末尾匹配,请输入:

ending_hash = {"e" => 1, "f" => 2} 
arr = ending_hash.find { |k,v| word.end_with?(k) }
  #=> nil
arr.nil? ? nil : arr.last
  #=> nil

或更好:

ending_hash.find { |k,v| word.end_with?(k) }&.last
  #=> nil

&Safe Navigation Operator。简而言之,如果&之前的表达式返回nil,则SNO会立即为整个表达式返回nil,而不执行last

即使word必须以键之一结尾,您也可能希望以这种方式编写它,以便您可以检查返回值并在nil处引发异常。

您也可以写:

ending_hash.find { |k,v| word.match? /#{k}\z/ }&.last

正则表达式为“匹配字符串末尾k#{k}\z)的 value ”。 / p>

请注意以下几点:

{"t"=>1, "st"=>2}.find { |k,v| word.end_with?(k) }&.last
  #=> 1
{"st"=>1, "t"=>2}.find { |k,v| word.end_with?(k) }&.last
  #=> 1

所以键的顺序可能很重要。

最后,由于在块计算中未使用块变量v,因此块变量通常会被写成|k,_||k,_v|,主要是向读者传达仅{ {1}}用于块计算。

答案 1 :(得分:0)

如果您知道结尾的 lengths 数量很少,那么检查所有可能的长度比检查所有结尾的速度要快得多。 (从最长到最短的位置检查它们也是有道理的,以防它们重叠,否则较短的将永远不会匹配。)

懒惰的一线客:

(-2..-1).lazy.map { |cut| ending_hash[word[cut..]] }.find(&:itself)

功能版本:

(-2..-1).inject(nil) { |a, e| a || ending_hash[word[e..]] }

钝但潮湿的版本:

ending_hash[word[-2..]] || ending_hash[word[-1..]]