キーワード引数を使う

#キーワード引数を使うとメソッドの引数が何を表しているかわかりやすくなる
def orderPizza(size: "M", qty: 1, crust:)
  puts "サイズ:#{size}、数:#{qty}、生地:#{crust}"
end
orderPizza(size: "L", qty: 2, crust:"Pan") #サイズ:L、数:2、生地:Pan

#デフォルト値がある場合は引数を省略できる
orderPizza(crust:"Pan") #サイズ:M、数:1、生地:Pan
参考文献

「プロを目指す人のためのRuby入門」

ハッシュ

#ハッシュを作る
hs =  {'a' => 1, 'b' =>2}
puts hs['a']#1

#値の設定
hs['a'] = 4
puts hs['a']#4

#繰り返し処理
#ブロック引数にキーと値が入る
hs.each do |k , v|
  puts "#{k} : #{v}"
end
# a : 4
# b : 2
#ブロック引数が1つだと配列にキーと値が入る
hs.each do |s|
  puts "#{s}"
end
# ["a", 4]
# ["b", 2]

#ハッシュのキーにはシンボルが向いている
#シンボルは見た目は文字列だが整数を扱っているので高速
hs1 =  {:a => 1, :b => 2}

#また=>を使うより簡潔に書ける:を使う。
hs2 =  {a: 1, b: 2}
参考文献

「プロを目指す人のためのRuby入門」

繰り返し処理

#eachメソッドで添え字を使いたい場合
s = ['a', 'b', 'c']
s.each_with_index { |c, i| puts "#{i}: #{c}"}
# 0: a
# 1: b
# 2: c

#2次元配列を繰り返すと配列がブロック変数に入る
a = [
  [1,2],
  [3,4],
  [5,6]
]
b = []
a.each do |i|
  b << i[0] + i[1]
end
puts b.to_s #[3, 7, 11]

i = 0
3.times { i += 1}
puts i

#Rubyではfor文はあるがあまり使わず、eachメソッドやmapメソッドを使い場合がほとんどらしい。

# break文にはif文が使える
a = [1,3,2,4,7,2]
a.each do |n|
  puts n
  break if n == 4 #4で繰り返しを抜ける

end
参考文献

「プロを目指す人のためのRuby入門」

配列について2

#メソッドの可変長
def plus (*s)
  "#{s.join('')}が引数に設定されました!"
end
puts plus(1,2,3) #1と2と3が引数に設定されました!

#配列に配列を展開したい場合は*をつける
#*をつけないと配列の配列になってしまう
a = [1,2,3]
puts [0, a].to_s #[0, [1, 2, 3]]
puts [0, *a].to_s #[0, 1, 2, 3]

#配列の値の比較
puts [1,2] == [1,2] #true
puts [1,2] == [2,1] #false

#文字列を配列に格納する
a = 'abcd'.chars
puts a.to_s #["a", "b", "c", "d"]

#引数で指定した文字で区切って配列に入れる
a = 'a b c d'.split(' ')
puts a.to_s #["a", "b", "c", "d"]

#初期化 aとbは同じこと
a = []
b = Array.new
puts a == b #true

#要素数を指定して初期化 aとbは同じこと
a = [nil,nil,nil,nil,nil]
b = Array.new(5)
puts a == b #true

#第1引数に要素数、第2引数に初期値を指定して初期化
a = [1,1,1,1,1]
b = Array.new(5, 1)
puts a == b #true

#ブロックを使って初期化。nには配列の添え字が設定される
a = Array.new(3) { |n| n*2}
puts a.to_s #[0, 2, 4]

# newの第2引数で初期化すると全要素が同じオブジェクトを参照
# ブロックを使って初期化すると各要素が異なるオブジェクトを参照
a = Array.new(3, 'abc') #["abc", "abc", "abc"]
b = Array.new(3){'abc'} #["abc", "abc", "abc"]
a[0].upcase! #破壊的変更
b[0].upcase! #破壊的変更
puts a.to_s #["ABC", "ABC", "ABC"] 全要素が変わる
puts b.to_s #["ABC", "abc", "abc"] upcaseメソッドを読んだ要素だけ変わる
参考文献

「プロを目指す人のためのRuby入門」

配列について

#最後の要素の取り方
a=[1,2,3,4,5]
a[-1] #=> 5
a.last #=> 5

#要素の追加
#<<でもpushでもできる。pushだと複数追加できる。
a=[1,2,3,4,5]
a << 6 #=> [1, 2, 3, 4, 5, 6]
a.push(7) #=> [1, 2, 3, 4, 5, 6, 7]
a.push(7,8) #=> [1, 2, 3, 4, 5, 6, 7, 7, 8]

#配列の変数で追加するときは*をつける。
b=[10,11]
a.push(*b) #=> [1, 2, 3, 4, 5, 6, 7, 7, 8, 10, 11]
# *をつけないと配列ごと追加されてしまう
a.push(b) #=> [1, 2, 3, 4, 5, 6, 7, 7, 8, 10, 11, [10, 11]]

#配列の連結
a=[1,2,3]
b=[7,8,9]
#concatを使うとaに連結した値が設定される
a.concat(b) #=> [1, 2, 3, 7, 8, 9]
a #=> [1, 2, 3, 7, 8, 9]
b #=> [7, 8, 9]
#+を使うとaとbの値は変わらない
a + b #=> [1, 2, 3, 7, 8, 9]
a #=> [1, 2, 3]
b #=> [7, 8, 9]

#集合を扱えるSetクラス
require 'set'
a = Set.new([0,1,2,3])
b = Set.new([0,7,8,9])
a | b #和集合<Set: {0, 1, 2, 3, 7, 8, 9}>
a - b #差集合<Set: {1, 2, 3}>
a & b #積集合<Set: {0}>
参考文献

「プロを目指す人のためのRuby入門」

範囲オブジェクトRange

範囲を表せるオブジェクト。
..や...を使って表す。

1..3 #1から3
1...3 #1から2

include?メソッドでは引数の値に含まれるか調べることができる。

(1..3).include?(3)
#=> true
(1...3).include?(3)
#=> false

<や<=を使った範囲の判定をシンプルに書くことができる。

age = 19
0 <= age && age < 20 #=> true
(0...20).include?(age) #=> true

age = 20
0 <= age && age < 20 #=> false
(0...20).include?(age)=> false

to_aメソッドを使って配列を作ることができる。

('a'..'e').to_a
#=> ["a", "b", "c", "d", "e"]
参考文献

「プロを目指す人のためのRuby入門」

ブロック

RubyではFor文は使うかわりにeachメソッドを使う。
Javaでいう拡張For文のようなもの。

s1 = ['a','b','c']
s2 = ""
s1.each do |s|
  s2 += s
end
puts s2 # abc

|s|のことをブロック変数という。配列から取り出した1要素が順に格納される。

do end を使わずに{ } で使って書くこともできる。
1行で書きたいときはこちらを使うらしい。

s1 = ['a','b','c']
s2=""
s1.each { |s| s2 += s }
puts s2# abc

ブロックを使うメソッド

# ブロックの戻り値を変数に入れられる
s1 = ['a','b','c']
s2 = s1.map { |s| s + '!' }
puts s2.to_s #["a!", "b!", "c!"]

# ブロックの戻り値が真になったものだけを入れる
s1 = ['a','b','c', 'b']
s2 = s1.select { |s| s == 'b' }
puts s2.to_s #=> ["b", "b"]

# selectメソッドの反対
s1 = ['a','b','c', 'b']
s2 = s1.reject { |s| s == 'b' }
puts s2.to_s #=> ["a", "c"]

# ブロックの戻り値が真になった最初の要素を返す
s1 = ['a','bbb','cccc', 'b']
s2 = s1.find { |s| s.size == 4 }
puts s2 #=> "cccc"

# sには最初だけinjectの引数が入る。
# 以降は前回のブロックの戻り値が入る。
# s2には各要素の値が入る。
s1 = ['a','b','c']
s2 = s1.inject('z') { |s, ss| s + ss }
puts s2 #=> "zabc"

&とシンボルを使ったもっと簡潔に書く方法
以下の条件を満たす時に使える。

  • ブロック変数が1つ
  • ブロック内で呼び出すメソッドに引数がない
  • ブロック内ではメソッドを1回呼び出すだけ

ブロック内でわざわざ変数を使う必要がないから省略する感じ?

s1 = ['a','b','c']
s2 = s1.map { |s| s.upcase }
puts s2.to_s #=>["A", "B", "C"]
#こう書き換えられる
s2 = s1.map(&:upcase)
puts s2.to_s #=>["A", "B", "C"]
参考文献

「プロを目指す人のためのRuby入門」