hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

レビューを読めるようにする

見たいレビューの順番を入力してそのレビューを表示させるようにする。

配列から要素を取り出す

配列から選んだ順番の要素を取得できるようにする。

配列は順番でオブジェクトを管理しているので、配列は順番を指定することでオブジェクトを取得することができる。以下の書き方で配列オブジェクトから指定した順番の要素を取得できる。

1
  配列オブジェクト[順番(数値)]

配列オブジェクトに続けて[](大括弧)とその中に取得したいオブジェクトの順番を指定する。

以下の配列オブジェクトanimalsから「いぬ」を取り出してputsメソッドで表示してみる。

sample.rb
1
  animals = ["いぬ", "ねこ", "ねずみ"]
 

 

配列の順番は0から始まります。つまりanimals[1]は配列animalsの2番目のオブジェクトを取得しているということになります。よって「いぬ」を取得するにはaminals[0]です。

sample.rb
1
2
  animals = ["いぬ", "ねこ", "ねずみ"]
  puts animals[0]                    # => "いぬ"

 

要点チェック

 

指定した順番のレビューを表示

レビューを読むのメソッドread_reviewsに書き足していく。

ここで作る機能は以下。

見たいレビューの番号を入力させる

メニューで[1]:レビューを読むを入力後

1
2
  見たいレビューの番号を入力してください:
  # 入力待ち

その番号のレビューのジャンル、タイトル、感想を表示する

レビューの番号を入力後

1
2
3
4
5
6
ジャンル : マンガ
---------------------------
タイトル : るろうに剣心
---------------------------
感想 : 映画もいいけどやっぱりマンガが最高!
---------------------------

 配列の要素数よりも大きい数字を入力してしまうと要素がなくエラーしてしまう。例えば3つしか要素の無い配列オブジェクトに対して配列オブジェクト[4]などとすると、5番目の要素はないためエラーになる。

要点チェック

 

レビューの一覧を表示

このままでは配列の何番目に何のレビューが入ってるかわかりません。そこで「レビューを読む」を選択したらレビューの一覧が表示されるようにする。
レビューの一覧ではそのレビューの「タイトル」とそのレビューの「順番」を表示させるようにする。

1
2
3
4
5
6
[0]:時をかける少女のレビュー
[1]:トレモロのレビュー
[2]:るろうに剣心のレビュー

見たいレビューの番号を入力してください:
# 入力待ち

レビューの一覧の表示をするには配列オブジェクトpostsの要素すべてに表示の処理を行う必要がある。

配列オブジェクトの要素すべてに共通の処理

配列の要素すべてに対して共通の処理を行うには配列の繰り返しを使う。繰り返しのためのメソッドはeachメソッド

 eachメソッド

配列オブジェクトに対してeachメソッドを実行すると、配列に含まれる要素を順に取り出して繰り返し処理が行われる。すなわち、配列の要素の数だけ処理が行われる。
eachメソッドの使い方は以下のように配列オブジェクトに使う。

1
2
3
  配列オブジェクト.each do |変数|
    # 処理
  end

変数には繰り返しごとに配列の要素が代入されていく

sample.rb
1
2
3
4
  animals = ["いぬ", "ねこ", "ねずみ"]
  animals.each do |animal|
    puts animal
  end

上のコードでは配列オブジェクトanimalsの要素を1つずつ変数animalに入れてputs animalの処理を行っている。配列の要素は動物の名前なので、その共通項をとって変数名をanimalにしている。

配列の要素["いぬ", "ねこ", "ねずみ"]のすべてが出力されていたはず。ちゃんと要素の数だけ繰り返されているかも、以下のプログラムで確認する。

sample.rb
1
2
3
4
5
6
7
  animals = ["いぬ", "ねこ", "ねずみ"]
  number = 0
  animals.each do |animal|
    puts animal
    number = number + 1
  end
    puts "#{number}回繰り返しました"

繰り返しの処理が実行される度に、変数numberに1を足していく。

素数は3つなので、処理は3回実行され、numberの値は3になるはず。
「3回繰り返しました」と出力されれば成功。

 

要点チェック

 

「レビューを読む」を入力したらレビューの一覧を表示

メニューで"[1]レビューを読む"を入力したらレビューの一覧を表示させてから見たいレビューの番号を入力させるようにする。レビューの一覧は以下のように
[順番]:"タイトル"のレビュー
というフォーマットで表示させる。

1
2
3
4
5
6
[0]:時をかける少女のレビュー
[1]:トレモロのレビュー
[2]:るろうに剣心のレビュー

見たいレビューの番号を入力してください:
# 入力待ち

 

reviewApp.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  # メソッドの定義
  def post_review(a_posts)
    # 変数の定義
    post = {}
    puts "ジャンルを入力してください:"
    post[:genre]  = gets.chomp
    puts "タイトルを入力してください:"
    post[:title]  = gets.chomp
    puts "感想を入力してください:"
    post[:review] = gets.chomp
    line   = "---------------------------"

    # レビューの描画
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"

    # 配列オブジェクトに追加
    a_posts << post

    # a_postsをメソッドの呼び出し元に返す
    return a_posts
  end

  def read_reviews(a_posts)
    # リストの表示
    number = 0
    a_posts.each do |post|
      puts "[#{number}]:#{post[:title]}のレビュー"
      number = number + 1
    end

    puts "\n見たいレビューの番号を入力してください:"
    input = gets.to_i

    # レビューの取得
    post = a_posts[input]

    # レビューの描画
    line   = "---------------------------"
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end

  def end_program
    exit
  end

  def exception
    puts "入力された値は無効な値です"
  end

  posts = []             # 配列オブジェクトpostsの生成

  while true do
    # メニューの表示
    puts "レビュー数:#{posts.length}"
    puts "[0]レビューを書く"
    puts "[1]レビューを読む"
    puts "[2]アプリを終了する"
    input = gets.to_i

    if input == 0 then
      posts = post_review(posts)  # post_reviewメソッドの呼び出し
    elsif input == 1 then
      read_reviews(posts)         # read_reviewsメソッドの呼び出し
    elsif input == 2 then
      end_program                 # end_programメソッドの呼び出し
    else
      exception                   # exceptionメソッドの呼び出し
    end
  end

解説

 

reviewApp.rb
25
26
27
28
29
30
31
32
33
34
35
36
37
  def read_reviews(a_posts)
    puts "見たいレビューの番号を入力してください:"
    input = gets.to_i

    # レビューの取得
    post = a_posts[input]

    # レビューの描画
    line   = "---------------------------"
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end

26行目のputs "見たいレビューの番号を入力してください:"の前にレビューの一覧を表示させる処理を書く。
まず、配列オブジェクトa_postsの要素をすべて表示させる。要素すべてに同じ処理を行うにはeachメソッドを使う。

reviewApp.rb
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  def read_reviews(a_posts)
    # リストの表示
    a_posts.each do |post|
      puts post
    end

    puts "見たいレビューの番号を入力してください:"
    input = gets.to_i

    # レビューの取得
    post = a_posts[input]

    # レビューの描画
    line   = "---------------------------"
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end

eachの||の間に書く変数名をpostにしているのは、配列a_postsに入っている要素が1つ1つの投稿、つまりはpostだから。

しかしこのままではレビューの出力が

ターミナル
1
{:genre=>"映画", :title=>"時をかける少女", :review=>"面白かった"}

というようにハッシュオブジェクトの形式になってしまっている。

今回表示させたいフォーマットは以下のような[順番]:"タイトル"のレビューというフォーマット。

ターミナル
1
2
3
[0]時をかける少女のレビュー
[1]トレモロのレビュー
[2]るろうに剣心のレビュー

ではまず、"タイトル"のレビューというフォーマットで出力させる。

reviewApp.rb
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  def read_reviews(a_posts)
    # リストの表示
    a_posts.each do |post|
      puts "#{post[:title]}のレビュー"
    end

    puts "見たいレビューの番号を入力してください:"
    input = gets.to_i

    # レビューの取得
    post = a_posts[input]

    # レビューの描画
    line   = "---------------------------"
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end

あとは、[順番]:をつけるだけ。eachメソッドによる繰り返し処理の前に順番用の変数numberを定義する。

reviewApp.rb
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  def read_reviews(a_posts)
    # リストの表示
    number = 0
    a_posts.each do |post|
      puts "#{post[:title]}のレビュー"
    end

    puts "見たいレビューの番号を入力してください:"
    input = gets.to_i

    # レビューの取得
    post = a_posts[input]

    # レビューの描画
    line   = "---------------------------"
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end

これを繰り返すたびに1ずつ増やしていけば順番が取得できますね。あとは出力するだけです。

reviewApp.rb
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  def read_reviews(a_posts)
    # リストの表示
    number = 0
    a_posts.each do |post|
      puts "[#{number}]:#{post[:title]}のレビュー"
      number = number + 1
    end

    puts "見たいレビューの番号を入力してください:"
    input = gets.to_i

    # レビューの取得
    post = a_posts[input]

    # レビューの描画
    line   = "---------------------------"
    puts "ジャンル : #{post[:genre]}\n#{line}"
    puts "タイトル : #{post[:title]}\n#{line}"
    puts "感想 :\n#{post[:review]}\n#{line}"
  end