【Rubyの基本】振り返る

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

平均を出力する

複数人のテストの点数のスコアが与えられるので、その平均値をeachを使ってすべて出力してください。

自分の解答

scores = [
  [10, 11, 22],
  [29, 11, 3, 1]
]

score1, score2 = scores

score1_total = 0
score1.each do |score|
  score1_total += score
end
score1_average = score1_total / score1.length
puts score1_average

score2_total = 0
score2.each do |score|
  score2_total += score
end
score2_average = score2_total / score2.length
puts score2_average

# 14
# 11

悩んだところ

配列の中に配列がある場合、どのように抜き出してよいか分からず。

とりあえず配列の中の配列を取り出し、それぞれ計算する始末。


解答

scores = [
  [10, 11, 22],
  [29, 11, 3, 1]
]
scores.each do |score|
  puts score.sum / score.size
end

【解説】
scoresに代入された配列内の配列をeach文でループさせてscoreに代入します。
scoreには[10, 11, 22]のように配列が入るので、sumメソッドを使って合計を、sizeメソッドを使って配列の要素数を計算してあげます。
合計を要素数で割ると平均が出るので、それをputsで出力できればOKです。


配列の最大値と最小値を配列で返す

数字のみが入った配列([1, 2, 345, 346, 299])を引数として、その配列の最大値と最小値を配列で返すメソッドmax_and_minを定義し、値を出力してください。

自分の解答

def max_and_min(array)
  max_min_array = []
  number_max = array.max
  number_min = array.min
  max_min_array.push(number_max)
  max_min_array.push(number_min)
  puts max_min_array
end

max_and_min([1, 2, 345, 346, 299])

# 346
# 1

悩んだところ
[346, 1]と出力させたいが、346、1としか出力されず。

でもputs max_min_array.classすると「Array」なので配列らしい・・・

解答

def max_and_min(array)
  p [array.max, array.min]
end
max_and_min([1, 2, 345, 346, 299])

# [346, 1]

【解説】
まず、引数を持つmax_and_minメソッドを定義してあげます。
解答例ではarrayとしていますが、好きな引数名で問題ありません。
メソッド内では、配列の最大値を取得するmaxメソッドと、配列の最小値を取得するminメソッドを使用します。
取得した値を配列にしてあげて配列をそのまま出力できるpメソッドで出力すると、出力値のように出力できます。

メソッドは、解答のようにメソッド名(引数)としてあげることで使用できます。


TRUE、FALSEの判定

2つの文字列が配列で与えられるので、その文字列が一致している場合は、TRUE、一致していない場合は、FALSE、と出力するメソッドcompare_strを定義してください。

自分の解答

def compare_str(str)
  str1, str2 = str
    if  str1 == str2
      puts "TRUE"
    else
      puts "FALSE"
    end
end

str = ['aaa', 'bbb']
compare_str(str)
# FALSE

str = ['aaa', 'aaa']
compare_str(str) 
# TRUE

前述「平均の出力」課題にて、配列を分割する術を覚えたのでこのやり方しか思い付かなくなっている。

解答

def compare_str(str)
  if str[0] == str[1]
    puts 'TRUE'
  else
    puts 'FALSE'
  end
end

指定の文字が含まれているか

特定の文字が与えられます。
その文字列に、?が含まれている場合、”疑問文”と出力するメソッドquestion_strを定義してください。

自分の解答

def question_str(str)
  if str.include?("?")
    puts "疑問文"
  end
end

str = 'こんにちは'
question_str(str)
puts "----------"
str = 'こんにちは?'
question_str(str)

解答

def question_str(str)
  puts '疑問文' if str.include?('?')
end

今回は文字列が「?」を含んでいない場合に何もしないので、後置ifを使って短く書いています。


正規表現

文字列がメールアドレス(●●●@△△△.■■■)の場合にのみ、そのメールアドレスを出力するメソッドputs_emailを定義してください。

自分の解答

def puts_email(str)
  m = str.match(/@/)
  puts str
end

str = 'aaa@gmail.com'
puts_email(str)

文字を複数指定する方法が分からず、大して調べもせずに「@」だけに妥協してしまう始末。

解答

def puts_email(str)
  puts str if str.match(/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i)
end

str = 'aaa@gmail.com'
puts_email(str) 


配列から抜き出して繋げる

名前の情報が保存されている配列が存在します。
その配列には、以下のように氏名が保存されています。
[{first_name: ‘taro’, family_name: ‘sato’}, {first_name: ‘rika’, family_name: ‘yamada’}]

すべての氏名を「氏 -> 名」の順番につなげて順番に出力してください。


また、出力する際は、名前同士の間に “, ” を入れて1つの文字列として出力してください。

自分の解答

names = [
  { first_name: 'taro', family_name: 'sato' },
  { first_name: 'rika', family_name: 'yamada' }
]

fullnames = []

names.map do |name|
  fullname = name[:family_name] + " " + name[:first_name]
  fullnames.push(fullname)
end

puts fullnames.join(",")
# sato taro,yamada rika

fullnames = [] を入れているため、コードが増えている

解答

names = [
  { first_name: 'taro', family_name: 'sato' },
  { first_name: 'rika', family_name: 'yamada' }
]
formatted_names = names.map do |name|
  "#{name[:family_name]} #{name[:first_name]}"
end
puts formatted_names.join(', ')

【解説】
mapメソッドを使うと新しい配列を返してくれるので、行数が少なくなります。
そのため、今回はmapメソッドを採用しましたが、eachメソッドを使用しても構いません。

mapメソッド内ではnameという変数に配列内のハッシュが代入されます。
そのハッシュ内の値をそれぞれ取得するため、name[:family_name]のようにキーを使ってあげます。
これでformatted_namesには[“sato taro”, “yamada rika”]という配列が入りました。
ここで、joinメソッドを使用して配列内の文字列を連結してあげます。
この時、引数に指定した文字列があるとその文字列が配列の各要素の間に入るので、出力値の名前の間にカンマが出力されます。

# DAY32