[英]How can I tell if my string contains a substring from an array?
How can I tell if my string contains a substring from an array? 如何判断我的字符串是否包含数组的子字符串?
I thought include?
我以为include?
was the key, but apparently not ... 是关键,但显然不是...
arr = ["aa", "bb", "cc"]
str = "mystringcc"
str.include?(*arr)
ArgumentError: wrong number of arguments (given 3, expected 1)
In the above example, I would expect the result to be true
since the string has "cc"
, which is an element of the array. 在上面的示例中,我希望结果为true
因为字符串具有"cc"
,这是数组的元素。
You want to use Enumerable# any?
您想使用Enumerable# any?
: :
arr.any? { |substring| str.include?(substring) }
The solution is very efficient, because this method ensures short-circuit evaluation , meaning, that if you have array of 100000000 substrings and you want to check whether your string contains any of these substrings, this method will stop right when its block returns true
, meaning, that if the matching substring is first in the array, it will never check other 99999999 elements. 该解决方案非常有效,因为此方法可确保进行短路评估 ,也就是说,如果您有100000000个子字符串数组,并且要检查字符串是否包含这些子字符串中的任何一个,则此方法将在其块返回true
时立即停止,这意味着,如果匹配的子字符串在数组中位于第一个,则它将永远不会检查其他99999999元素。
Construct a Regular Expression (without pipes and slashes and dots and other magic stuff): 构造一个正则表达式(不包括管道,斜线和点以及其他不可思议的东西):
arr = ["aa", "bb", "cc"]
str = "mystringcc"
reg = Regexp.union(arr) # That's all!
p str.match?(reg) #=> true
The reason you are getting that error message is because the *
operator is telling Ruby to pass all the items of arr
to str.include?
您收到该错误消息的原因是因为*
运算符告诉Ruby将arr
所有项目传递给str.include?
. 。 For those arr
items, that is equivalent to writing str.include?("aa", "bb", "cc")
. 对于这些arr
项,相当于编写str.include?("aa", "bb", "cc")
。
As said in other answers, checking a condition is verified for any of the elements contained in an array, like in your case (where you don't want to check if all the elements of an array are substrings of a given string), is done using arr.any? { |item| str.include?(item) }
如其他答案中所述,检查条件是否已针对数组中包含的任何元素进行了验证,例如在您的情况下(您不想检查数组的所有元素是否都是给定字符串的子字符串),使用arr.any? { |item| str.include?(item) }
完成arr.any? { |item| str.include?(item) }
arr.any? { |item| str.include?(item) }
arr.any? { |item| str.include?(item) }
. arr.any? { |item| str.include?(item) }
。
Given: 鉴于:
arr = ["a", "b", "x"]
str = "DoDox"
EDIT : As the other comments have pointed out, this is actually the fastest way, as it breaks the evaluation when a single true statement is found: 编辑 :正如其他评论所指出的那样,这实际上是最快的方法,因为当找到单个true语句时它将破坏评估:
arr.any?{|substr| str.include?(substr)}
The foldl way: I have used this example to illustrate the power of folding expresions. 的与foldl方式:我已经使用这个例子来说明折叠expresions的功率。 This solution might be somewhat elegant as an illustrative example for foldings, but it is not sufficiently performant. 作为折叠的说明性示例,该解决方案可能有些优雅,但性能不足。
arr.map{|substr| str.include?(substr)}.inject{|x,y| x || y}
The map
-function maps all possible substrings the original string str
can have. map
-function映射原始字符串str
可以具有的所有可能的子字符串。 inject
iterates over the returning array and compares its constituents, using a logical or. 使用逻辑或将inject
迭代返回的数组并比较其组成。 If any substring in the array 'arr' is encountered, the result will yield true in the result of map. 如果遇到数组“ arr”中的任何子字符串,则结果将在map结果中产生true。 With the or-relation we return a true value, if any value of the result of map was true. 如果map结果的任何值为true,则使用or-relation返回一个true值。 This is slower than any?
这比any?
慢any?
, because every single value in the array gets evaluated even if a true
is encountered (wich would always yield a true
at the end of inject
). ,因为即使遇到true
也会对数组中的每个值进行求值(wich总是在inject
末尾产生true
)。
["a", "b", "x"] -------> [false, false, true] ----------> true
map() inject()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.