weotch
weotch

Reputation: 5878

Loop through an array of grouped data in ruby (rails)

Say you have an ordered array like this, generated from a database of addresses:

[
  { city: Sacramento, state: CA },
  { city: San Francisco, state: CA },
  { city: Seattle, state: WA }
]

And you want to generate HTML with it like this:

<p>CA</p>
<ul>
    <li>Sacramento</li>
    <li>San Francisco</li>
</ul>
<p>WA</p>
<ul>
    <li>Seattle</li>
</ul>

So you're grouping by state. One approach to doing this would be to remember the last row on each iteration of the loop and to display the state and bookending UL tags only if the current row's state is the same as the last rows state. That seems kind of nasty and non Ruby-y.

Anyone have any advice on an elegant Ruby/Rails approach to this?

Upvotes: 7

Views: 5567

Answers (3)

Jonas Elfstr&#246;m
Jonas Elfstr&#246;m

Reputation: 31428

Enumerable has group_by

cities = [
  { city: "Sacramento", state: "CA" },
  { city: "San Francisco", state: "CA" },
  { city: "Seattle", state: "WA" }]

cities.group_by {|c| c[:state]}


=> {"CA"=>[{:city=>"Sacramento", :state=>"CA"}, 
           {:city=>"San Francisco", :state=>"CA"}], 
    "WA"=>[{:city=>"Seattle", :state=>"WA"}]}

I'm kind of rusty on ERB but I think it would be something like this

<% @cities_by_state.each do |state, cities| %>
<p><%= state %></p>
<ul>
  <% cities.each do |city| %>
    <li><%= city[:city] %></li>
  <% end %>
</ul>
<% end %>

Upvotes: 9

Shiv
Shiv

Reputation: 8412

You can use the group_by function in Rails

@records.group_by{|x| x[:state]}

This will return you a Hash where the key is the state and the values are an array of the records

This link should help you figure out how it works a little more.

Upvotes: 0

Mladen Jablanović
Mladen Jablanović

Reputation: 44080

Enumerable#group_by ?

array = [
  {city: 'Sacramento', state: 'CA'},
  {city: 'San Francisco', state: 'CA'},
  {city: 'Seattle', state: 'WA'}
]

array.group_by{|elem| elem[:state]}
# => {"CA"=>[{:city=>"Sacramento", :state=>"CA"}, {:city=>"San Francisco", :state=>"CA"}], "WA"=>[{:city=>"Seattle", :state=>"WA"}]} 

Upvotes: 8

Related Questions