Skip to content

Instantly share code, notes, and snippets.

@mitchty
Created November 22, 2011 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitchty/1384831 to your computer and use it in GitHub Desktop.
Save mitchty/1384831 to your computer and use it in GitHub Desktop.
Dumb oneliner challenge
# So to explain this contrived example a bit. Say you have an array of input that you wanted to match with
# multiple regexes how do you in ~1 line match the lot of things.
#
# So say for a given input of %w/ab abc abcde bcde bc efgh etc/
# You have multiple regexes to match against, in this case its just an array of strings that we build regexes off of.
#
# This is my kitbash first try.
#
# Anyone have any better ideas? I know you could just union them both if === works as your comparison:
# %w/ab abc bc bcde efgh/ & %w/ab bc/
# ["ab", "bc"]
all = %w/ab abcd abcdef bcde bc ladkfjlkadsjfja lajflkajfkaf/
matches = %w/ab bc/
p all.dup.keep_if {|l| matches.collect {|r| l !~ /#{r}/}.include?(false) }
p all.dup.keep_if {|l| matches.collect{|r| not l !~ /#{r}/}.include?(true)}
# Output (order is unimportant)
# ["ab", "abcd", "abcdef", "bcde", "bc"]
# ["ab", "abcd", "abcdef", "bcde", "bc"]
@mitchty
Copy link
Author

mitchty commented Nov 22, 2011

This also works.
p all.dup.delete_if {|l| matches.collect{|r| l !~ /#{r}/}.inject(:&)}

["ab", "abcd", "abcdef", "bcde", "bc"]

@krbullock
Copy link

Not sure where this Regexp#& method is coming from (my ri lists it, but irb throws NoMethodError). But in any case, here's a better way:

Regexp.union(*matches).tap {|r| break all.select {|l| l =~ r } }

Notably:

  1. Uses #select
  2. Avoids iterating over matches (twice!) for each element of all
  3. Sets up the regular expression once, reuses the same compiled instance for each iteration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment