質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

3回答

971閲覧

ruby 年齢出現数ランキング

sho-ab

総合スコア2

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2021/12/24 08:56

編集2021/12/24 09:47

rubyを勉強中です。プログラムについての質問なのですが、「氏名,氏名(カタカナ),性別,電話番号,郵便番号,住所,,,,,生年月日,年齢,血液型」の情報が記入されているテキストファイルを読み込んで、男性と女性の年齢の出現数トップ3を求めて出力するプログラムを作成したいのですが、どのようにすればいいのかわかりません。
よろしくおねがいします。
現在できているプログラムはこのような感じです。case文を利用すれば行けるのではないかと考えていますが。。。

while line =gets line.chomp! line_array = line.split(',') #case line??

出力の仕方は
男性   女性
1 90  33
2 77  45
3 88  20
のように出力しなければなりません。

ありがとうございます。一例ではありますが、載せます。
横井富男,ヨコイトミオ,男,0182375938,013-0372,秋田県,横手市,大雄上田村南,2-2-12,,1925/09/05,94,O
蛭田真奈美,ヒルタマナミ,女,0985629509,883-0005,宮崎県,日向市,中堀町,3-19-15,プレイス中堀町412,1927/02/03,92,O
碓井公男,ウスイキミオ,男,0997793480,899-1611,鹿児島県,阿久根市,赤瀬川,4-16-11,,1979/12/22,39,A
木村砂登子,キムラサトコ,女,0541639064,420-0964,静岡県,静岡市葵区,柳原,4-5-14,,1985/01/08,34,B
塩見重義,シオミシゲヨシ,男,0762303654,923-0155,石川県,小松市,江指町,4-19-16,,2000/07/18,19,O
秋田冨美子,アキタフミコ,女,0970998132,876-0062,大分県,佐伯市,古市,3-6-8,,1965/05/24,54,A
松尾彩那,マツオアヤナ,女,0835487340,755-0027,山口県,宇部市,港町,3-8-17,,1932/05/27,87,O
倉橋太輔,クラハシタイスケ,男,0342109539,136-0074,東京都,江東区,東砂,2-19-17,,2011/01/11,8,B
小笠原冴月,オガサワラサツキ,女,0768271282,939-8243,富山県,富山市,押上,2-20-20,,2017/02/15,2,O
平林百合子,ヒラバヤシユリコ,女,0476534656,299-3256,千葉県,大網白里市,山口,1-17-10,山口コンフォート206,1974/04/23,45,B
藤谷勝三,フジタニカツゾウ,男,0767375365,927-2335,石川県,輪島市,門前町黒岩,3-11-2,,1928/10/14,91,B
坂東利朗,バンドウトシオ,男,0520486406,488-0041,愛知県,尾張旭市,南新町中畑,2-16,,1959/03/23,60,O
武内晃一朗,タケウチコウイチロウ,男,0936363628,814-0003,福岡県,福岡市早良区,城西,4-4,パレス城西319,1961/02/06,58,A
水上美来,ミズカミミク,女,0599345997,519-3812,三重県,尾鷲市,名柄町,1-5,ザ名柄町400,1958/10/29,61,A
中塚央一郎,ナカツカオウイチロウ,男,0187215651,019-1847,秋田県,大仙市,南外小出,1-10-17,ステーション南外小出206,2018/12/23,0,B
これが何百行と書いてあるといった感じです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatsu99

2021/12/24 09:35 編集

テキストファイルの内容も提示してください。 質問は編集できます。質問のほうにのせてください。
guest

回答3

0

入力する CSV ファイルにヘッダ行(「氏名,氏名(カタカナ),性別,...」)が付いているのであれば、CSV::table を使っても良いかもしれません。以下では質問文にある CSV データを data.csv としています(全て異なる年齢ですので、データの内容を水増ししています)。

ruby

1require 'csv' 2 3table = CSV.read('data.csv', headers: true, converters: :numeric) 4ranking = \ 5 table.group_by{|g| g["性別"]} 6 .map{|gender, rows| [gender, 7 CSV::Table.new(rows, headers: table.headers) 8 .group_by{|g| g["年齢"]}.map{|age, r| [age, r.count]} 9 .sort_by{|e| e[1]}.reverse[...3].collect(&:first)]} 10 11ranking.map(&:flatten).transpose.each_with_index{|(m, w), idx| 12 idx == 0 ? printf("%5s%3s\n", m, w) : printf("%2d%4d%4d\n", idx, m, w) 13} 14 15# 16 男 女 17 1 39 61 18 2 30 45 19 3 58 34

投稿2021/12/25 05:30

編集2021/12/25 06:57
melian

総合スコア19703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2021/12/25 05:32

間違えてしまいました、、、修正します。
melian

2021/12/25 06:05

修正終了しました。
sho-ab

2021/12/28 09:23

回答していただきありがとうございました。今回CSVはまだ学習外だったため、ベストアンサーにはできませんでしたが、存在を知り、学ぶことができました。ありがとうございます。
guest

0

ベストアンサー

1つの例です。
101個の配列を作成し、年齢を添え字にします。出現回数は、その添え字が示す値です。
例 man[19] の内容が 5 の場合、男性の19歳の出現回数が5回。
不明点があれば質問してください。

Ruby

1man = Array.new(100,0) 2woman = Array.new(100,0) 3File.open("sample.txt","r") do |file| 4 while line = file.gets 5 line.chomp! 6 line_array = line.split(',') 7 age = line_array[11].to_i 8 case line_array[2] 9 when '男' 10 man[age] += 1 11 when '女' 12 woman[age] += 1 13 end 14 end 15end 16manmax = man.max(3) 17womanmax = woman.max(3) 18p man #途中経過の表示(不要なら削除) 19p manmax #途中経過の表示(不要なら削除) 20p woman #途中経過の表示(不要なら削除) 21p womanmax #途中経過の表示(不要なら削除) 22print "\t男性\t女性\n" 23(0..2).each do |i| 24 mx = man.index(manmax[i]) 25 man[mx] = 0 26 wx = woman.index(womanmax[i]) 27 woman[wx] = 0 28 print "#{i+1}\t#{mx}\t#{wx}\n" 29end 30

投稿2021/12/25 03:10

tatsu99

総合スコア5438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sho-ab

2021/12/28 09:24

回答していただきありがとうございます。今回学んでいることに近かったのでtatsu99様のソースコードを参考にさせていただきましたのでベストアンサーにさせていただきました。ありがとうございました。
guest

0

勉強途中と言うことですが、
・配列の扱い方
・条件文
は勉強を終えてないのでしょうか?
配列はいろいろ機能があるので勉強途中で全部知っている必要は全くないのですが、条件文が書けず、男女別の年齢の配列が作れないとすると、まだこのプログラムを書くには早いと言うことになるかと思います。

年齢のカウントは、Rubyらしいやり方としては、Rubyにはいろいろ便利なメソッドがあるので、メソッド一覧をじっくり眺めて、使えそうなメソッドがないかを探します。
今回は、group_byを使うと、[10,8,15,10,9,8,13,15]のような年齢の配列から、{10=>[10, 10], 8=>[8, 8], 15=>[15, 15], 9=>[9], 13=>[13]}のように年齢の値で分類できますので、これを値の個数でソート(sort_by)して、先頭3つを取れば良い(take)です。

Ruby

1p [10,8,15,10,9,8,13,15].group_by{_1}.sort_by{-(_2.count)}.map(&:first).take(3)

細かい考慮点としては、3位までに同順位が複数あった場合、その中の1つだけを取って全体で3つ表示するのか(上記コード)、同順位を全部で3つを超えても全部表示するのか、どっちにするのかを決める必要があります。

投稿2021/12/24 10:05

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2021/12/25 12:30

参考までに書いておくと、Rubyらしい書き方だと、この場合はif等は出てきません。 result = STDIN.readlines #全部読む .map{|x| w=x.split(/,/);[w[2],w[11]]} #必要な性別と年齢のみの抜き出し .group_by{|x| x[0]} #男女で分類 .map{|k,v| [k,v.group_by{|x,y| y}.sort_by{|x,y| -y.count}.map(&:first).take(3)]} #回答参照 p result
sho-ab

2021/12/28 09:29

回答していただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問