【问题标题】:Use current argument of splat operator使用 splat 运算符的当前参数
【发布时间】:2013-11-13 12:59:53
【问题描述】:

我有一个汽车品牌列表

 makes = [acura, honda, ford]

我正在尝试遍历一个字符串数组,并找出单个字符串是否包含其中一个品牌,如果包含,则将该特定品牌放入一个数组中

所以我有

strings.each do |string|

  if string.include?(*makes)

  else

  end
end

如何使用 splat 进程的当前参数来确定与字符串匹配的组成?有没有办法做到这一点?

编辑:正如我在下面的 cmets 中发布的那样,我正在寻找要返回的特定品牌,而不是真/假答案。所以如果字符串是“New toyota celica”,返回应该是“toyota”。

【问题讨论】:

  • 您可以单独检查每个品牌。
  • 实际项目中实际上有 40 多个品牌,所以这不是一件容易的事! :)

标签: ruby arrays splat


【解决方案1】:

另一种方式,通过数组相交:

makes = ["acura", "honda", "ford"]

strings = [
"I own a Toyota and a Ford",
"My friend Becky loves her Acura",
"I plan to buy a BMW",
"I now have an Acura, but have had both a honda and a Ford"
]

strings.each do |s|
  a = s.scan(/(\w+)/).flatten.map(&:downcase) & makes
  puts "#{s}\n" + (a.empty? ? "  No matches" : "  Matches: #{a.join}")
end

I own a Toyota and a Ford
  Matches: ford
My friend Becky loves her Acura
  Matches: acura
I plan to buy a BMW
  No matches
I now have an Acura, but have had both a honda and a Ford
  Matches: acura honda ford

请注意,必须将scan 与正则表达式一起使用,而不是split,因为后者会出现标点符号问题(例如,'Acura' 将不匹配)。

【讨论】:

    【解决方案2】:

    使用Enumerable#any?:

    makes = ['acura', 'honda', 'ford']
    strings = ['hyundai acura ford', 'sports car']
    
    strings.each do |string|
      p makes.any? { |make| string.include? make }
    end
    

    使用正则表达式的替代方案:(参见Regexp::union

    strings = ['hyundai acura ford', 'sports car']
    makes = ['acura', 'honda', 'ford']
    pattern = Regexp.union(makes)
    
    strings.each do |string|
      p string.match(pattern) != nil
    end
    

    更新

    strings.each do |string|
      p makes.find { |make| string.include? make }
    end
    

    strings.each do |string|
      p makes.select { |make| string.include? make }
    end
    

    【讨论】:

    • 在这里使用String#join 很丑。你应该使用Regexp.union
    • @sawa,谢谢您的建议。我根据您的评论更新了答案。
    • 有趣,问题仍然悬而未决 - 有必要逃避。
    • @sawa,根据Regexp documentation,记为::union。实际上Regexp::unionRegexp.union 都可以接受。
    • @EdgarsJekabsons, Regexp::union 转义字符串。例如,Regexp.union(['a.b', '^$']) 产生 /a\.b|\^\$/
    【解决方案3】:

    如果您的makes 不是很长,那么最短的方法之一就是使用正则表达式,正如已经建议的那样:

    makes = ['acura', 'honda', 'ford']
    strings = ['hyundai acura ford', 'sports car']
    strings.grep(/#{makes.join('|')}/)
    
     # => ["hyundai acura ford"]
    

    经过轻微讨论,我们认为这是最佳选择之一:

    strings.grep(Regexp.union(makes))
    

    【讨论】:

    • 如果你想写 - makes *('|')... :)
    猜你喜欢
    • 2012-07-29
    • 2013-07-04
    • 1970-01-01
    • 2021-10-18
    • 2018-07-20
    • 2017-07-09
    • 2017-11-17
    • 2014-03-11
    • 2023-01-18
    相关资源
    最近更新 更多