Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何查看一个字符串是否包含关键字列表中的关键字?_Ruby - Fatal编程技术网

Ruby 如何查看一个字符串是否包含关键字列表中的关键字?

Ruby 如何查看一个字符串是否包含关键字列表中的关键字?,ruby,Ruby,我想看看一个字符串是否包含关键字列表中的关键字 我有以下功能: def needfilter?(src) ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].each do |kw| return true if src.include?(kw) end false end 这个代码块可以简化成一行句子吗 我知道可以简化为: def needfilter?(src) !

我想看看一个字符串是否包含关键字列表中的关键字

我有以下功能:

def needfilter?(src)
    ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].each do |kw|
        return true if src.include?(kw)
    end
    false
end   
这个代码块可以简化成一行句子吗

我知道可以简化为:

def needfilter?(src)
    !["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].select{|c| src.include?(c)}.empty?
end

但是,如果关键字数组列表很长,这种方法就没有那么有效。

看起来是一个很好的方法用例:


看起来是一个很好的方法用例:

我认为

def need_filter?(src)
  (src.split(/ /) & ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"]).empty?
end
将按照您的期望工作(如中所述),并且将比
任何?
包括?
更快,我认为

def need_filter?(src)
  (src.split(/ /) & ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"]).empty?
end
def need_filter?(src)
  !!(src =~ /keyowrd_1|keyowrd_2|keyowrd_3|keyowrd_4|keyowrd_5/)
end
将按照您的预期工作(如中所述),并且将比
任何?
包括?
更快

def need_filter?(src)
  !!(src =~ /keyowrd_1|keyowrd_2|keyowrd_3|keyowrd_4|keyowrd_5/)
end
=~
方法返回fixnum或nil。双重爆炸将其转换为布尔值


=~
方法返回fixnum或nil。双重爆炸将其转换为布尔值。

我很好奇什么是最快的解决方案,我创建了一个到目前为止所有答案的基准

我改了一点。出于调优的原因,我只为每个测试创建一次regexp

require 'benchmark'
KEYWORDS = ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"]
TESTSTRINGS = ['xx', 'xxx', "keyowrd_2"]

N = 10_000 #Number of Test loops

def needfilter_orig?(src)
    ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].each do |kw|
        return true if src.include?(kw)
    end
    false
end 
def needfilter_orig2?(src)
    !["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].select{|c| src.include?(c)}.empty?
end
def needfilter_any?(src)
  ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].any? do |kw|
    src.include? kw
  end
end
def needfilter_regexp?(src)
  !!(src =~ Regexp.union(KEYWORDS))
end
def needfilter_regexp_init?(src)
  !!(src =~ $KEYWORDS_regexp)
end
def needfilter_split?(src)
  (src.split(/ /) & KEYWORDS).empty?
end

Benchmark.bmbm(10) {|b|

  b.report('orig') { N.times { TESTSTRINGS.each{|src| needfilter_orig?(src)} } }
  b.report('orig2') { N.times { TESTSTRINGS.each{|src| needfilter_orig2?(src) } } }
  b.report('any') { N.times { TESTSTRINGS.each{|src| needfilter_any?(src) } } }
  b.report('regexp') { N.times { TESTSTRINGS.each{|src| needfilter_regexp?(src) } } }
  b.report('regexp_init') { 
   $KEYWORDS_regexp = Regexp.union(KEYWORDS) # Initialize once
    N.times { TESTSTRINGS.each{|src| needfilter_regexp_init?(src) } }
  }
  b.report('split') { N.times { TESTSTRINGS.each{|src| needfilter_split?(src) } } }

} #Benchmark
结果:

Rehearsal -----------------------------------------------
orig          0.094000   0.000000   0.094000 (  0.093750)
orig2         0.093000   0.000000   0.093000 (  0.093750)
any           0.110000   0.000000   0.110000 (  0.109375)
regexp        0.578000   0.000000   0.578000 (  0.578125)
regexp_init   0.047000   0.000000   0.047000 (  0.046875)
split         0.125000   0.000000   0.125000 (  0.125000)
-------------------------------------- total: 1.047000sec

                  user     system      total        real
orig          0.078000   0.000000   0.078000 (  0.078125)
orig2         0.109000   0.000000   0.109000 (  0.109375)
any           0.078000   0.000000   0.078000 (  0.078125)
regexp        0.579000   0.000000   0.579000 (  0.578125)
regexp_init   0.046000   0.000000   0.046000 (  0.046875)
split         0.125000   0.000000   0.125000 (  0.125000)

如果只创建一次regexp,使用正则表达式的解决方案是最快的。

我很好奇什么是最快的解决方案,我创建了一个到目前为止所有答案的基准

我改了一点。出于调优的原因,我只为每个测试创建一次regexp

require 'benchmark'
KEYWORDS = ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"]
TESTSTRINGS = ['xx', 'xxx', "keyowrd_2"]

N = 10_000 #Number of Test loops

def needfilter_orig?(src)
    ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].each do |kw|
        return true if src.include?(kw)
    end
    false
end 
def needfilter_orig2?(src)
    !["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].select{|c| src.include?(c)}.empty?
end
def needfilter_any?(src)
  ["keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5"].any? do |kw|
    src.include? kw
  end
end
def needfilter_regexp?(src)
  !!(src =~ Regexp.union(KEYWORDS))
end
def needfilter_regexp_init?(src)
  !!(src =~ $KEYWORDS_regexp)
end
def needfilter_split?(src)
  (src.split(/ /) & KEYWORDS).empty?
end

Benchmark.bmbm(10) {|b|

  b.report('orig') { N.times { TESTSTRINGS.each{|src| needfilter_orig?(src)} } }
  b.report('orig2') { N.times { TESTSTRINGS.each{|src| needfilter_orig2?(src) } } }
  b.report('any') { N.times { TESTSTRINGS.each{|src| needfilter_any?(src) } } }
  b.report('regexp') { N.times { TESTSTRINGS.each{|src| needfilter_regexp?(src) } } }
  b.report('regexp_init') { 
   $KEYWORDS_regexp = Regexp.union(KEYWORDS) # Initialize once
    N.times { TESTSTRINGS.each{|src| needfilter_regexp_init?(src) } }
  }
  b.report('split') { N.times { TESTSTRINGS.each{|src| needfilter_split?(src) } } }

} #Benchmark
结果:

Rehearsal -----------------------------------------------
orig          0.094000   0.000000   0.094000 (  0.093750)
orig2         0.093000   0.000000   0.093000 (  0.093750)
any           0.110000   0.000000   0.110000 (  0.109375)
regexp        0.578000   0.000000   0.578000 (  0.578125)
regexp_init   0.047000   0.000000   0.047000 (  0.046875)
split         0.125000   0.000000   0.125000 (  0.125000)
-------------------------------------- total: 1.047000sec

                  user     system      total        real
orig          0.078000   0.000000   0.078000 (  0.078125)
orig2         0.109000   0.000000   0.109000 (  0.109375)
any           0.078000   0.000000   0.078000 (  0.078125)
regexp        0.579000   0.000000   0.579000 (  0.578125)
regexp_init   0.046000   0.000000   0.046000 (  0.046875)
split         0.125000   0.000000   0.125000 (  0.125000)

如果只创建一次regexp,则使用正则表达式的解决方案是最快的。

这是我的方法:

def needfilter?(src)
    keywords = Regexp.union("keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5")
    !!(src =~ keywords)
end
此解决方案具有:

  • 无迭代
  • 使用regexp.union的单个regexp

即使是一大组关键字也应该是快速的。请注意,在方法中硬编码关键字并不理想,但我假设这只是为了示例的缘故。

我会这样做:

def needfilter?(src)
    keywords = Regexp.union("keyowrd_1","keyowrd_2","keyowrd_3","keyowrd_4","keyowrd_5")
    !!(src =~ keywords)
end
此解决方案具有:

  • 无迭代
  • 使用regexp.union的单个regexp

即使是一大组关键字也应该是快速的。请注意,在方法中硬编码关键字并不理想,但我假设这只是为了示例的缘故。

src是一个字符串,根据这个问题。我通过将所有字符串拆分为单词来修复它。谢谢,但是这种方法失败了,src字符串可能非常复杂。我认为这不是很有效,因为我只想知道字符串命中任何关键字,如果是,忽略其他关键字,只返回truesrc是字符串,根据问题。我通过将所有字符串拆分为单词来修复它。谢谢,但是这种方法失败了,src字符串可能非常复杂。我认为这不是很有效,因为我只想知道字符串命中了任何关键字,如果是这样,忽略其他关键字并返回true。你也可以用
/{keywords.join('.')}/
构建正则表达式(假设关键字不包含符号)。这可能是最快的解决方案。但是试着对所有答案进行基准测试。你也可以用
/#{keywords.join('|')}/
(假设关键字不包含符号)构建正则表达式。这可能是最快的解决方案。但是试着对所有答案进行基准测试。谢谢,你的方法非常好。在我的实际代码中,关键字来自一些额外的配置,这里我只想知道哪个解决方案更好。这就是我的想法。通过只计算一次联合关键字并将结果regexp存储在方法外部(例如属性中),可以节省更多时间。那么您的整个方法定义就是
!!(src=~@keywords)
。Ruby的正则表达式引擎也很快,所以在使用大型正则表达式模式时不会受到影响。谢谢,你的方法非常好。在我的实际代码中,关键字来自一些额外的配置,这里我只想知道哪个解决方案更好。这就是我的想法。通过只计算一次联合关键字并将结果regexp存储在方法外部(例如属性中),可以节省更多时间。那么您的整个方法定义就是
!!(src=~@keywords)
。Ruby的正则表达式引擎也很快,所以在使用大型正则表达式模式时不会受到影响。