LoginSignup
0
0

Ruby芸160チャレンジ(#18)group_byからのcount

Posted at

この記事は何

shellgei160を通じて言語習得 Advent Calendar 2023に参加しています。

書籍「シェル芸ワンライナー160本ノック」の例題をRubyで解いてみて、Rubyの学習に役立てようとするものです。

例題はこちらのリポジトリで公開されているものに限ります。
https://github.com/shellgei/shellgei160

実行環境など

  • Docker image: ruby:3.0.2
  • 上記リポジトリをクローンした上で、リポジトリのルートディレクトリ直下にanswer-rubyディレクトリを作り、その中に解答となるファイルを作成していきます。

今回のテーマ

$ declare -A x ; IFS=: ; while read {a..g} ; do x[$g]+=. ; done < /etc/passwd ; for s in ${!x[@]} ; do echo $s ${#x[$s]}; done ; unset x

/etc/passwdの中に登場するshellについて、それぞれのshellごとに個数をカウントする処理です。

出力例
/bin/bash 1
/bin/sync 1
/usr/sbin/nologin 17

# /etc/passwd を行ごとに読み込んで、7番目のフィールド = シェル名があれば取り込む
shells = File.open('/etc/passwd', 'r').readlines.map do |line|
  fields = line.split(':')
  nil if fields.size < 7
  fields[6].chomp
end

# シェルの種類ごとに集計する
# group_by(&:itself)だけでは各キーごとに要素をまとめた配列が得られるだけなので
# transform_values(&:count)で各要素の数を数える必要がある
counts = shells.sort.group_by(&:itself).transform_values(&:count)
counts.each do |shell, count|
  puts "#{shell} #{count}"
end

所感

  • group_by(Enumeratorモジュール)は、ブロック内の値ごとに要素をまとめる。なるほど。(&:itself)とすることで、同じ値のものをまとめることになる。
  • transform_valuesもいろいろ使えそうで良い。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0