A lot of people know about enumerable’s two methods select and reject. They’re both extremely useful when you only want a subset of whatever you’re iterating through.

In certain scenarios, you need the results of both select and reject in thier own iterable lists. In the past, I would just do the following:

  list  = [1, 2, 3, 4, 5, 6, 7]
  evens = list.select{|i| i % 2 == 0 }
  odds  = list.reject{|i| i % 2 == 0 }

This works fine, but you’ll notice you’re doing two iterations through the list. I was curious if there was a way to achieve the results with a single iteration, and sure enough, enumerables have partition.

The partition method returns takes a block like select and reject, but returns two enumerables instead of one. The first array has the items in the list that the block returned a true result, and the second array holding the items that the block returned a false result.

Rewriting the code above now looks like the following.

  list  = [1, 2, 3, 4, 5, 6, 7]
  evens, odds = list.partition{|i| i % 2 == 0 }

I really like the cleanliness of this method. The fact that the assignment of the lists happen on the same makes it very clear to me that we’re splitting the list on the results of the block.