0

Sorry I'am new on Ruby (just a Java programmer), I have two string arrays:

  • Array with file paths.
  • Array with patterns (can be a path or a file)

I need to check each patter over each "file path". I do with this way:

@flag = false
["aa/bb/cc/file1.txt","aa/bb/cc/file2.txt","aa/bb/dd/file3.txt"].each do |source|
  ["bb/cc/","zz/xx/ee"].each do |to_check|
    if source.include?(to_check)
      @flag = true
    end
  end 
end
puts @flag

This code is ok, prints "true" because "bb/cc" is in source.

I have seen several posts but can not find a better way. I'm sure there should be functions that allow me to do this in fewer lines. Is this is possible?

2
  • 1
    Have you read the docs for Ruby's Enumerable? Check out Enumerable#any?. Commented Nov 28, 2016 at 20:20
  • @dodecaphonic Thanks for help me. I will check Ruby's enumerable. Commented Nov 29, 2016 at 0:35

2 Answers 2

4

As mentioned by @dodecaphonic use Enumerable#any?. Something like this:

paths.any? { |s| patterns.any? { |p| s[p] } }

where paths and patterns are arrays as defined by the OP.

Sign up to request clarification or add additional context in comments.

Comments

1

While that will work, that's going to have geometric scaling problems, that is it has to do N*M tests for a list of N files versus M patterns. You can optimize this a little:

files = ["aa/bb/cc/file1.txt","aa/bb/cc/file2.txt","aa/bb/dd/file3.txt"]

# Create a pattern that matches all desired substrings
pattern = Regexp.union(["bb/cc/","zz/xx/ee"])

# Test until one of them hits, returns true if any matches, false otherwise
files.any? do |file|
  file.match(pattern)
end

You can wrap that up in a method if you want. Keep in mind that if the pattern list doesn't change you might want to create that once and keep it around instead of constantly re-generating it.

2 Comments

Doesn't the regex engine have to perform up to M tests when evaluating file.match(pattern) for up to N files?
@CarySwoveland The regular expression itself runs in fairly short amounts of time, and for something trivial like this it's basically O(N).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.