Posts Tagged ‘any’

Ruby Enumerable Magic: Booleans

December 3, 2010

  1. The Basics
  2. Unary Ampersand Operator
  3. Booleans
  4. Filters
  5. New Collections
  6. Aggregates
 

The most basic Enumerable methods are those that give you a simple yes/no answer. There are three of these boolean methods: all?, any?, and include?. Each gives you quick info about the collection you’re working on.

We’ll start out our Team class from previous articles:

class Team
  include Enumerable
  
  attr_accessor :members
  
  def initialize
    @members = []
  end
  
  def each &block
    @members.each{|member| block.call(member)}
  end
end

all?

This method tells you if *every* item in your collection matches the criteria you give it. Let’s test it out:

irb(main):001:0> require 'team.rb'
=> true
irb(main):002:0> team = Team.new
=> #<Team:0x100391088 @members=[]>
irb(main):003:0> team.members = ['joshua', 'gabriel', 'jacob']
=> ["joshua", "gabriel", "jacob"]
irb(main):004:0> team.all?{|member| member.length > 4}
=> true
irb(main):005:0> team.all?{|member| member.length > 5}
=> false

Here we’re checking to see if all members (which are just strings containing their names) meet a certain length. All of the names have more than four characters, so all? returns true. However, only two of the three names contain more than five letters, so all? returns false in the second test.

Whatever block you pass to all? will be evaluated for each item in the collection (members in this case) and the method will only return true if all items return true.

any?

all? is a little strict, like an uptight parent demanding “all” your dirty clothes be put in the hamper. Wouldn’t it be nice to get partial credit? any? promotes permissive searches and parenting by only requiring that one item in the collection meet the given criteria. As long as any item evaluates to true (using the block you pass in), the whole collection gets the thumbs up.

irb(main):001:0> require 'team.rb'
=> true
irb(main):002:0> team = Team.new
=> #<Team:0x100391088 @members=[]>
irb(main):003:0> team.members = ['joshua', 'gabriel', 'jacob']
=> ["joshua", "gabriel", "jacob"]
irb(main):004:0> team.any?{|member| member == 'joshua'}
=> true
irb(main):005:0> team.any?{|member| member == 'javier'}
=> false

The example above is like a party. When you open the door and see three people standing there, you really only need to know *one* of them, and they’re all welcome. In the first example, if anybody in the team is named “joshua”, the whole collection is green-lighted for beer and awkward dancing. In the second example, if you don’t have a “javier” on your team, you’ll have to stay in the hallway, drinking the beer you brought yourself, and standing awkwardly.

include?

This is my favorite boolean enumerable method, simply because I always forget how to spell it. I always want to type includes? when the collection name is singular (like “team”). But it makes sense when the collection is plural, as in members.include?.

Our examples above can be shortened to use the include? syntax:

irb(main):001:0> require 'team.rb'
=> true
irb(main):002:0> team = Team.new
=> #<Team:0x100391088 @members=[]>
irb(main):003:0> team.members = ['joshua', 'gabriel', 'jacob']
=> ["joshua", "gabriel", "jacob"]
irb(main):004:0> team.include?('joshua')
=> true
irb(main):005:0> team.include?('javier')
=> false

First, note that include? doesn’t take a block – it takes one parameter, an item. This method will check the whole collection to see if that item is in there, and return true or false.

The Enumerable module contains a handful of handy boolean methods, but the real power comes in filtering collections down to the desired items. As luck would have it, that’s the topic of my next article.


Follow

Get every new post delivered to your Inbox.