32423hjh32423
32423hjh32423

Reputation: 3088

Group by part of attribute in hash

I have a model called coverage that looks like this

1.9.3p429 :005 > Coverage.new
=> #<Coverage id: nil, postcode: nil, name: nil, created_at: nil, updated_at: nil>

Here is an example record:

1.9.3p429 :006 > Coverage.find(10)
Coverage Load (7.3ms)  SELECT "coverages".* FROM "coverages" WHERE "coverages"."id" = $1 LIMIT 1  [["id", 10]]
=> #<Coverage id: 10, postcode: "N10", name: "N10 - Muswell Hill", created_at: "2013-05-22 14:42:37", updated_at: "2013-05-22 14:42:37">

I've got over 300 postcodes and I want to group them by some values I have in this array

group = ['N','E','EC','LS','TS']

So I would like to do

@postcodes = Coverage.all

run it through something with the above array to get the following hash

@postcode_hash = { 'N' => [ '#Active Record for N1', '#Active Record for N2' ], 'E' => [ '#Active Record for E1', '#Active Record for E2' ] } 
# note: not complete should contain all index from the above array

Upvotes: 3

Views: 2394

Answers (1)

MrYoshiji
MrYoshiji

Reputation: 54902

You can use the .group_by{} method:

@postcodes = Coverage.all
@postcodes_hash = @postcodes.group_by{ |c| c.postcode.gsub(/[0-9]/, '') }

Take a look at the group_by documentation: http://apidock.com/rails/Enumerable/group_by

There is the explicit version of above:

@postcode_hash = {}
group = ['N','E','EC','LS','TS']
group.each{ |code| @postcode_hash[code] = [] }

@postcodes = Coverage.scoped # similar to .all but better
@postcodes.map do |coverage|
  code = coverage.postcode.gsub(/[0-9]/, '') # takes off all the numbers of the postcode
  @postcode_hash[code] << coverage if @postcode_hash[code]
end

Upvotes: 3

Related Questions