Edited at

特定のカラムの初めの頭文字でグループ化する方法

More than 3 years have passed since last update.


はじめに

ブランド情報を管理するBrandモデル&実際のデーターが以下のような状況の時にアルファベットごとにグループ化する方法がすぐにわからなかったのでメモっておきます


app/models/brand.rb

# == Schema Information

#
# Table name: brands
#
# id :integer not null, primary key
# name :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class Brand < ActiveRecord::Base
end

{ "name": "titivate"},

{ "name": "MERCURYDUO"},
{ "name": "GYDA"},
{ "name": "jouetie"},
{ "name": "PAMEO POSE"},
{ "name": "MURUA"},
{ "name": "dazzlin"},
{ "name": "merry jenny"},
{ "name": "Re:EDIT"},
{ "name": "Agneau7"},
{ "name": "ANAP"},
{ "name": "Apuweiser-riche"},
{ "name": "AULA AILA"},
{ "name": "BACKS"},
{ "name": "Boisson Chocolat"},
{ "name": "BONICA DOT"},
{ "name": "bpb"},
{ "name": "BUBBLES"},
{ "name": "Candy Stripper"},
{ "name": "X-girl"},
{ "name": "UNRELISH"},
{ "name": "deicy"},
{ "name": "chuu"}


最初に考えた書き方

こんなのを思いつきました。

mapが2回出てくる時点でちょっと気持ち悪いし、これだと後でメンテナンスするのはちょっとツライなぁと思ってました

@brands = Brand.all

brands_group_by_alphabet = ("A".."Z").map do |alp|
{
alphabet: alp ,
brands: @brands.select{|brand| brand.name[0] == alp}.map{|brand| brand}}
end


もっとスッキリ書ける

ActiveRecordでgroup Byしてカウントをして、カウント数でorderするを読んで、group Byできることを知りました。

この記事で突破口が開けた感じがしたものの、アルファベットごとにどのようにグループ化すればいいのかすぐにわからなかったのですがRubyリファレンス見て以下のようにすることで意図したことができました。

Brand.all.group_by {|brand| brand.name.chr.upcase }.sort

=> [["A",
[#<Brand:0x007fc42fed8398
id: 11,
name: "Agneau7",
#<Brand:0x007fc42fed8230
id: 12,
name: "ANAP",
#<Brand:0x007fc42fed80c8
id: 13,
name: "Apuweiser-riche",]],
["U",
[#<Brand:0x007fc430abb3b8
id: 22,
name: "UNRELISH"]],
["X",
[#<Brand:0x007fc430abb520
id: 21,
name: "X-girl",
>]]]

少し補足すると

することでアルファベットごとにグループ出来ます。