Home
1/10/20152
1/4/2015
12/28/2014
12/14/2014
12/13/2014
12/6/2014
11/30/2014
11/29/2014
11/23/2014
11/22/2014
11/15/2014
11/12/2014
11/8/2014
11/1/2014
10/31/2014

November 22
2014

.group_by

I have to start by giving credit to Anna Taberski. If she hadn't shown this to me, while we were pairing, I would've never understood it. Even now I'm referring to our code to make sure I'm explaining it correctly.

.group_by does something that few other methods I've come across do. It takes an array or hash, and returns a hash. Most methods will return strings, integers or arrays, but not good 'ole .group_by (.select and .reject are the only others I've found). One would use this method for collecting and reorganizing objects from an array or hash by the result of a block of code.

One example of using .group_by would be to take the data grouped into a hash and organize it by commonality. If you wanted to find the even numbers in an array:

irb(main):001:0> [1,2,3,4,5,6,7,8,9].group_by{|obj| obj%2}
=> {1=>[1, 3, 5, 7, 9], 0=>[2, 4, 6, 8]}

This shows all of the numbers, from the array, that return a 1, from modulus 2, and the numbers that return 0.

This process can be developed into a more elaborate process though.

irb(main):001:0> ["cat", "dog", "cow", "dolphin", "camel", "giraffe", "elephant"].group_by {|obj|
irb(main):002:1* if obj.include?("c")
irb(main):003:2> "c"
irb(main):004:2> elsif obj.include?("d")
irb(main):005:2> "d"
irb(main):006:2> elsif obj.include?("e")
irb(main):007:2> "e"
irb(main):008:2> end
irb(main):009:1> }
=> {"c"=>["cat", "cow", "camel"], "d"=>["dog", "dolphin"], "e"=>["giraffe", "elephant"]}

I realize that camel has a "c" and an "e", but since the first if statement satisfied the condition on .include?("c") the .group_by moved on to the next item in the array.

You can also do this with hashes. In the code that Anna and I wrote, we used a hash to store our boots and their group number, and then used .group_by to put them into arrays that we could more easily manage.(This is only a fraction of the list)

irb(main):001:0> {"Edward Mitchell"=>1, "John Nicholas Mandalakas"=>2, "Matthew Gray"=>3, "Aaron Harris"=>4, "Gabriela Voicu"=>5}.group_by{|k,v| v}
=>{1=>[["Edward Mitchell", 1]], 2=>[["John Nicholas Mandalakas", 2]], 3=>[["Matthew Gray", 3]], 4=>[["Aaron Harris", 4]], 5=>[["Gabriela Voicu", 5]]}

After this we obviously had to clean it up, but you can see how each name/number array is grouped into a numbered hash. The actual hash contained several arrays of arrays {1 => [[Name,1],[Name,1],[Name,1],[Name,1]], 2 => [[Name,2],[Name,2],[Name,2],[Name,2]], ...}

In the end, the most important thing to realize when using .group_by is that the keys will always be what is returned in the block, and the values are going to be what is passed into the block. If you're passing a single object, like with an array, your values will be single objects. If you're passing multiple objects, like with a hash, your values will be arrays of objects(key/value pairs).