Thursday, 5 March 2015

group_by is cool in Ruby :)

I am getting this object and I have to display these records on category basis

data = [{"category":"xyz","label":"test xyz label1","link":"testlink"},
{"category":"xyz","label":"test xyzlabel2","link":"testlink"},
{"category":"abc","label":"test abc label1","link":"testlink"},
{"category":"abc","label":"test abc label2","link":"testlink"},
{"category":"def","label":"test def label1","link":"testlink"},
{"category":"def","label":"test def label2","link":"testlink"}]

Desired Output:

  category 1
    record 1
    record 2
  category 2
    record 1
    record 2

Previously I was Using the following code.
- category = ""
- data.each do |d|
  - if category != d[:category]
    - category = d[:category]
    %h2= d[:category]
    %ul
  %li= d[:label]

  
The code I mentioned Displayed the records in order displayed above But this will break incase if we get response as:
data = [{"category":"xyz","label":"test xyz label1","link":"testlink"},
{"category":"abc","label":"test abc label1","link":"testlink"},
{"category":"xyz","label":"test xyzlabel2","link":"testlink"},
{"category":"def","label":"test def label1","link":"testlink"},
{"category":"abc","label":"test abc label2","link":"testlink"},
{"category":"def","label":"test def label2","link":"testlink"}]

The above code will Display:
category 1
  record 1
category 2
  record 1
category 1
  record 2
category 3
  record 1

for solving this Problem I changed my approach and used group_by, it takes a block as an argument and returns a hash,
by using group_by the scenario we have discussed will be handelled easily.

- data.group_by{ |d| d[:category] }.each do |d|
  %h2= d.first
  %ul
  - d.last.each do | result |
    %li = result[:label]

  
this reduced my code and now it looks better.

No comments:

Post a Comment