読者です 読者をやめる 読者になる 読者になる

simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

rubyのgroup_byが便利

Rubyのgroup_byメソッドが便利です。要素をグループ分けするためのメソッドなのですが、色々と応用が効きそうです。まずは、簡単な例から。

names = %w(ruby python java c++ php javascript perl lisp haskell)

group = names.group_by do |name|
  name[0] # 先頭文字の種類によって分類
end

p group
{"r"=>["ruby"], "p"=>["python", "php", "perl"], "j"=>["java", "javascript"], "c"=>["c++"], "l"=>["lisp"], "h"=>["haskell"]}

group_byではブロック文の返り値毎にグループ分けを行うので、今回は先頭文字の種類でグループ分けを行いました。他にも文字列のサイズごとに分類なんてこともできます。


names = %w(ruby python java c++ php javascript perl lisp haskell)

group = names.group_by do |name|
  name.size # 文字列の長さ毎に分類
end

p group
{4=>["ruby", "java", "perl", "lisp"], 6=>["python"], 3=>["c++", "php"], 10=>["javascript"], 7=>["haskell"]}

4文字の言語が多いですね。(サンプル数が少ない)


OpenStructを使ってテストの点数によるランク分けをしてみる。

この便利なgroup_byメソッドとOpenStructを合わせて、簡単なテストの点数のランク分けを実装してみる。

require 'ostruct'

students = []
students << OpenStruct.new({name: "siman", eng: 90, math: 90, science: 90, ave: 90})
students << OpenStruct.new({name: "hoge", eng: 80, math: 70, science: 30, ave: 60})
students << OpenStruct.new({name: "piyo", eng: 0, math: 100, science: 20, ave: 40})

group = students.group_by do |student|
  case student.ave
  when 0...20
    "E"
  when 20...40
    "D"
  when 40...60
    "C"
  when 60...80
    "B"
  when 80..100
    "A"
  end
end

group.each do |rank, students|
  students.each do |student|
    puts "#{student.name}さんのランクは#{rank}です。"
    puts "英語の得点 : %3d点" % [student.eng]
    puts "数学の得点 : %3d点" % [student.math]
    puts "科学の得点 : %3d点" % [student.science]
    puts "    平均点 : %3d点" % [student.ave]
    puts "------------------------------------------"
  end
end
simanさんのランクはAです。
英語の得点 :  90点
数学の得点 :  90点
科学の得点 :  90点
    平均点 :  90点
------------------------------------------
hogeさんのランクはBです。
英語の得点 :  80点
数学の得点 :  70点
科学の得点 :  30点
    平均点 :  60点
------------------------------------------
piyoさんのランクはCです。
英語の得点 :   0点
数学の得点 : 100点
科学の得点 :  20点
    平均点 :  40点
------------------------------------------

生徒の平均点からランクを割り当て、そのランク毎に生徒の詳細な点を表示する簡単なシステムを作ってみました。こんな簡単に実装できるなんて素晴らしいです。