#map_find 在 Ruby 中?

Posted

技术标签:

【中文标题】#map_find 在 Ruby 中?【英文标题】:#map_find in Ruby? 【发布时间】:2020-01-16 21:58:32 【问题描述】:

返回一组文本行中匹配的第一个关键字。

我发现#map#find#find 再次解决了问题。一个不令人满意的复杂解决方案。

["unrelated", "start something", "stop something"].map do |t|
  ["start","stop"].find |k| k == t.split(/[ \t]1,/).first
end.find |k| !k.nil?

上述返回"start" 符合预期。 #map_find 这样的便捷方法可以压缩它。或者可能已经存在针对这个问题的聪明的选择算法。请指教。


编辑

另一种解决方案:

keys = ["start", "stop"]
reg = Regexp.new("^"+keys.first+" |^"+keys.last+" ")
["unrelated", "start something", "stop something"].map|m| m.slice(reg).find |k| !k.nil?

【问题讨论】:

从您的示例中有点不清楚哪个顺序更重要 - 行中的顺序或关键字。如果关键字是%w[stop start] 或行是['stop something', 'start something'],那么在这种情况下,您是否仍然期望返回start 或期望stop 在你的例子中,我希望stop。匹配关键字的第一行定义了返回的关键字。 这也可以:keyword = arr.find |a| a[/\A(start|stop)\b/] && Regexp.last_match[0](或更短:arr.find |a| a[/\A(start|stop)\b/] && $1 您的实现仍然比我的快 4 倍。到现在已经节省了十分之二秒 :) 【参考方案1】:

我会这样做:

lines = ["unrelated", "start something", "stop something"]
keywords = /\A(start|stop)/

lines.lazy.map  |line| line[keywords] .find(&:itself)
#=> "start"

lines 的数量很少时,您可能希望跳过lazy。它越大,您从lazy 中受益越多。

【讨论】:

我需要返回匹配的关键字,而不是行。 出于某种原因,您的原始解决方案比我的任何一个都快 11 倍。 因为lazy——这增加了一些初始开销——我的版本将map直到找到匹配的行然后立即返回。您的版本将在检查条件之前首先评估所有行 - 即使匹配已经在第二个元素上(如您的示例中)。 lazy 增加了一致的惩罚,速度基本和我的一样。如果没有最新版本,速度会快 4 倍。 正如我在回答中已经写的那样。如果行数很大,请仅使用lazy。数量少的话不值得。

以上是关于#map_find 在 Ruby 中?的主要内容,如果未能解决你的问题,请参考以下文章

ruby find_ruby_files_in_project.rb

使用 find_by 加载 Ruby on Rails

ruby finds_page.rb

ruby 多态find_blablaable

ruby find_duplicate.rb

ruby find_a_payment.rb