Chirag Shah
Chirag Shah

Reputation: 640

Filter array with an array of regex

I am using Ruby 1.9.2p320 and running the following code snippet:

a = ["abc", "def", "pqr", "xyz"]
z = ["abc", "xyz"]
a.grep(/#{z}/)

That gives this output: ["abc", "xyz"].

a = ["abc_1", "def_1", "pqr_1", "xyz_1"]
z = ["abc_1", "xyz_1"]
a.grep(/#{z}/)

But this gives output as: ["abc_1", "def_1", "pqr_1", "xyz_1"].

What I expected was just ["abc_1", "xyz_1"].

Any particular reason why am i getting that output? And how could I get the expected output?

Upvotes: 1

Views: 135

Answers (3)

toro2k
toro2k

Reputation: 19238

You are building the regexp the wrong way, you should do something like:

a = ["abc_1", "def_1", "pqr_1", "xyz_1"]
z = ["abc_1", "xyz_1"]

a.grep(Regexp.union(z))
# => ["abc_1", "xyz_1"]

Your first example seems to work because #{z} is interpolated as the following expression:

/["abc", "xyz"]/

That is a chararcters class that matches only against "abc" and "xyz". In the second example #{z} is iterpolated as the following characters class:

/["abc_1", "xyz_1"]/

That matches all the strings in the array since they all include the character 1.

Upvotes: 5

Pritesh Jain
Pritesh Jain

Reputation: 9146

Both the answers above are perfectly fine as per your question.

but if you are working with arrays why not use & operator

a = ["abc_1", "def_1", "pqr_1", "xyz_1"]
z = ["abc_1", "xyz_1"]
a & z
=> ["abc_1", "xyz_1"]

same answer as using grep and simpler

Upvotes: 2

Marek Lipka
Marek Lipka

Reputation: 51191

Try this:

a.grep(/#{z.join('|')}/)
# => ["abc_1", "xyz_1"]

It creates valid regexp - with regexp "or" statement - /abc_1|xyz_1/

Upvotes: 3

Related Questions