err had a great article on the many uses of inject the other day. Here’s a bit of code I was working on today. Similar to the popular “sum” example, I’m using inject to perform multiple logical “or’s”.

1
2
3
4
5
6
7
8
9
10
# An example of or'ing tests on everything in an array
# asking the question "is our letter equal to anything in this array?"
>> arrrr = ["a", "b", "c"]
=> ["a", "b", "c"]
>> arrrr.inject(false) { |n,m| n or (m=="b") }
=> true
>> arrrr.inject(false) { |n,m| n or (m=="a") }
=> true
>> arrrr.inject(false) { |n,m| n or (m=="x") }
=> false

What an over-simplified example – in fact, we could have just used include? to do the work of that example. Let’s try something a little more relevant. I have a couple ActiveRecord models called User and UserGroup. They are related by “has and belongs to many”. Peep this code, I use to check if a user is in any one of the groups I give in a list:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# somewhere inside class User

  # takes one group name and returns true if the user is in it
  def is_in_group?(group_name)
    self.user_groups.include? UserGroup.find_by_name(group_name)
  end

  # takes an array of groups and returns true if the user is in at least one of those groups
  # ex: user.is_in_any_groups?(['administrators', 'support staff']) == true
  def is_in_any_groups?(group_list)
    group_list.inject(false) { |n,m| n or self.is_in_group?(m) }
  end

  # takes an array of groups and returns true if the user is in at least one of those groups
  def is_in_any_groups?(group_list)
    group_list.inject(true) { |n,m| n and self.is_in_group?(m) }
  end

Notice the base value passed to inject is "false" for a series of or operations, but you have to start with "true" if you want to perform a series of and operations.

3 Responses to “ruby's inject and logic operations”

  1. Chris Says:

    Cool post, nice to see some alterna-versions of inject. Don’t forget about any? and all?, though:

    { |g| user.user_groups.include? UserGroup.find_by_name(group_name) }
  2. Chris Says:

    Whoops, where are my manners? Try this instead: http://pastie.caboo.se/36006

  3. Jason Says:

    Ah, awesome. That’s why I love ruby – she thinks of everything!

Sorry, comments are closed for this article.