Ruby 101: How to filter an Array using proc

Over at the PhRUG, a Ruby developer community based in the Philippines, we conduct code review sessions via our mailing list. A code is posted and members share alternative implementations. So far, it’s been effective and newbies and veterans alike are learning new things in Ruby. Here’s a recent code that filters an array based on several conditions.

  matches = []
  (0..9).each do |i|
   if (i > 5) && (i % 2).zero? &&  (i % 3).zero?
     matches << i
   end
  end

The first improvement made by Bong is to use ‘select’.

  matches = (0..9).select {|i| (i > 5) && (i % 2).zero? &&  (i % 3).zero?}

What if you are going to include another condition? Of course, you can argue to simply hard code the new condition but that wouldn’t be fun 🙂 The solution by Tim and Neil is to use procs which I’m sure would make Matz very happy.

    conditions = [
       proc { |i| i > 5 },
       proc { |i| (i % 2).zero? },
       proc { |i| (i % 3).zero? }
     ]
    
    elements = (1..10).to_a
    
    matches = elements.select do |i|
      conditions.all? { |c| c[i] }
    end
    
    puts matches.join(',')

We can even add this filtering to the Array class, just in case we need to use this across our application.

    class Array
      def matches(*conditions)
        select do |i|
          conditions.all? { |c| c[i] }
        end
      end
    end
    
    matches = elements.matches(*conditions)
    puts matches.join(',')
    
    matches = elements.matches( proc{ |i| i > 5 })
    puts matches.join(',')
    
    matches = elements.matches( proc{ |i| i > 5 }, proc{ |i| (i%3).zero? })
    puts matches.join(',')
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s