如何判断我的字符串是否包含数组中的子字符串?

时间:2017-05-16 14:40:21

标签: arrays ruby string substring ruby-2.4

如何判断我的字符串是否包含数组中的子字符串?

我认为include?是关键,但显然不是......

arr = ["aa", "bb", "cc"]
str = "mystringcc"
str.include?(*arr)
ArgumentError: wrong number of arguments (given 3, expected 1)

在上面的例子中,我希望结果为true,因为字符串有"cc",这是数组的一个元素。

4 个答案:

答案 0 :(得分:10)

您想使用Enumerable#any?

arr.any? { |substring| str.include?(substring) }

该解决方案非常有效,因为此方法可确保短路评估,这意味着,如果您有100000000个子串的数组,并且您想要检查您的字符串是否包含任何这些子字符串,当它的块返回true时,方法将停止,这意味着,如果匹配的子字符串在数组中是第一个,它将永远不会检查其他99999999个元素。

答案 1 :(得分:4)

构造一个正则表达式(没有管道,斜线和点以及其他神奇的东西):

arr = ["aa", "bb", "cc"]
str = "mystringcc"
reg = Regexp.union(arr)  # That's all!
p str.match?(reg)        #=> true

答案 2 :(得分:0)

您收到该错误消息的原因是*运算符告诉Ruby将arr的所有项目传递给str.include?。对于那些arr项,这相当于编写str.include?("aa", "bb", "cc")

正如在其他答案中所说的,检查条件是否包含在数组中的任何元素,例如你的情况(你不想检查数组的所有元素是否是给定字符串的子字符串) ),使用arr.any? { |item| str.include?(item) }完成。

答案 3 :(得分:-1)

假设:

arr = ["a", "b", "x"]
str = "DoDox"

编辑:正如其他评论所指出的,这实际上是最快的方式,因为它在找到单个真实语句时会破坏评估:

arr.any?{|substr| str.include?(substr)}

foldl方式:我用这个例子来说明折叠表达的力量。作为折叠的说明性示例,这种解决方案可能有些优雅,但效率不高。

arr.map{|substr| str.include?(substr)}.inject{|x,y| x || y}

map - 函数映射原始字符串str可能具有的所有可能子字符串。 inject遍历返回的数组并使用逻辑或者比较其成分。如果数组中的任何子字符串'arr'遇到,结果将在map的结果中产生true。如果map的结果的任何值为true,则使用or-relation返回true值。这比any?要慢,因为即使遇到true,也会评估数组中的每个值(在true结束时总会产生inject

["a", "b", "x"] -------> [false, false, true] ----------> true
                 map()                          inject()
相关问题