really breaking up an array

December 6th, 2007

Last time I tried to break up an array, I learned about enumerable’s partition method. This time, I’m taking it one step further and returning multiple arrays rather than just two:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Array
  def group_by(attribute = nil)
    arrays = {}
    for i in 0...size
      object = self[i]
      value = attribute ? object.send(attribute.to_sym) : yield(object)
      if arrays[value.to_s]
        arrays[value.to_s] << object
      else
        arrays[value.to_s] = [object]
      end
    end
    return arrays.values
  end
end

And, the examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>> # you can group by attribute name
>> my_array = ["cats", "dogs", "people", "things", "elephants", "computers", "cars", "1001"]
=> ["cats", "dogs", "people", "things", "elephants", "computers", "cars", "1001"]
>> my_array.group_by "size"
=> [["people", "things"], ["elephants", "computers"], ["cats", "dogs", "cars", "1001"]]

>> # also can take a block - equal evaluation of the block determines grouping
>> my_array.group_by { |a| a[0] }
=> [["things"], ["cats", "computers", "cars"], ["1001"], ["dogs"], ["elephants"], ["people"]]

>> [4, "foo", 500, "bar", 4.5].group_by { |a| a.is_a? Integer }
=> [[4, 500], ["foo", "bar", 4.5]]

>> [4, "foo", 500, "bar", 4.5].group_by { |a| a.to_s.size }
=> [[4], ["foo", 500, "bar", 4.5]]

Again, I find this method useful for grouping ActiveRecord sets based on different attributes. It's especially handy when constructing views where records need to be grouped under different headings or in different tables.

Sorry, comments are closed for this article.