Arnold Roa
Arnold Roa

Reputation: 7748

How to check in ruby if an string contains any of an array of strings

I have an array of strings a, and I want to check if another long string b contains any of the strings in the array

a = ['key','words','to', 'check']
b = "this is a long string"

What different options do I have to accomplish this?

For example this seems to work

not a.select { |x| b.include? x }.empty?

But it returns a negative response, thats why I had not, any other ideas or differents ways?

Upvotes: 5

Views: 8243

Answers (3)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84453

Scan and Flatten

There are a number of ways to do what you want, but I like to program for clarity of purpose even when it's a little more verbose. The way that groks best to me is to scan the string for each member of the array, and then see if the flattened result has any members. For example:

a = ['key','words','to', 'check']
b = "this is a long string"
a.map { |word| b.scan /#{word}/ }.flatten.any?
# => false

a << 'string'
a.map { |word| b.scan /#{word}/ }.flatten.any?
# => true

The reason this works is that scan returns an array of matches, such as:

=> [[], [], [], [], ["string"]]

Array#flatten ensures that the empty nested arrays are removed, so that Enumerable#any? behaves the way you'd expect. To see why you need #flatten, consider the following:

[[], [], [], []].any?
# => true
[[], [], [], []].flatten.any?
# => false

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118299

There you go using #any?.

a = ['key','words','to', 'check']
b = "this is a long string"
a.any? { |s| b.include? s }

Or something like using ::union. But as per the need, you might need to change the regex, to some extent it can be done. If not, then I will go with above one.

a = ['key','words','to', 'check'] 
Regexp.union a
# => /key|words|to|check/ 
b = "this is a long string"
Regexp.union(a) === b # => false 

Upvotes: 16

Brandon Buck
Brandon Buck

Reputation: 7181

You could also use the array intersection (#&) method:

a = ['key','words','to', 'check']
b = "this is a long string"
shared = a & b.gsub(/[.!?,'"]/, "").split(/\s/)

Which would return an array containing all the shared characters.

Upvotes: 0

Related Questions