【问题标题】:Ruby fast and fuzzy search array of lots of hashesRuby 快速模糊搜索大量哈希数组
【发布时间】:2018-10-01 13:33:39
【问题描述】:

我有一个这样的哈希数组

@t = [{"id"=>"819827", "nm"=>"Razvilka", "countryCode"=>"RU"}, 
{"id"=>"524901", "nm"=>"Moscow", "countryCode"=>"RU"}, 
{"id"=>"1271881", "nm"=>"Firozpur Jhirka", "countryCode"=>"IN"}, 
{"id"=>"1283240", "nm"=>"Kathmandu", "countryCode"=>"NP"}] # ... + 100,000 more

我可以从具有精确拼写的特定哈希键中进行搜索,例如

@t.find {|x| x["nm"] == "Moscow"}

它会很快返回散列。

但这不会考虑大小写、语法或近似匹配。我该怎么做?

【问题讨论】:

  • 定义语法或近似匹配
  • 如果拼写为“moscow”或“mosc”或“MoScoV”等,它应该能够返回任何匹配的东西?
  • 我认为您应该使用库(如建议的那样)而不是自己动手做的工作。
  • 也许是正则表达式,@t.find {|x| x["nm"][/moscow/i] } 但就像我说的,不能确定它有多耐用。另请注意 find 仅返回第一个匹配项。对所有匹配项使用select
  • 尽管我希望能够为您提供一个快速的纯 Ruby 解决方案,但您是否考虑过将这些数据加载到数据库(甚至是启用了 Soundex 的 SQLite)并在那里进行模糊搜索?

标签: arrays ruby sorting search hash


【解决方案1】:

试试 levenshtein gem https://rubygems.org/gems/levenshtein

gem install levenshtein

然后在您的代码中:

require `levenshtein`

#Levenshtein.distance(a, b) < 5 # some fuzzy level

def find_levenshtein(hash, key, str)
  hash.select do |h|
    Levenshtein.distance(h[key], str) < 5
  end
end

puts find_levenshtein(t, 'nm', 'moscw').inspect
#=> [{"id"=>"524901", "nm"=>"Moscow", "lat"=>"55.752220", "lon"=>"37.615555", "countryCode"=>"RU"}]

欲了解更多信息,请参阅https://en.wikipedia.org/wiki/Levenshtein_distance

【讨论】:

  • Levenstshtein 并不总是有效。在大部分时间进行测试时,我不得不不断改变模糊级别以获得预期的结果。所以目前我很简单地进行正则表达式搜索。我还尝试了 sim_string 算法,该算法效果很好,但不足以挑战正则表达式!我认为不存在用于修复模糊性的低开销解决方案。
猜你喜欢
  • 2013-04-13
  • 2011-01-15
  • 2016-08-29
  • 2015-11-15
  • 1970-01-01
  • 2013-11-29
  • 2012-04-10
  • 2015-08-14
  • 2015-12-16
相关资源
最近更新 更多