Skip to content

Instantly share code, notes, and snippets.

@sasaki-shigeo
Created September 18, 2012 17:40
Show Gist options
  • Save sasaki-shigeo/3744549 to your computer and use it in GitHub Desktop.
Save sasaki-shigeo/3744549 to your computer and use it in GitHub Desktop.
Examples of Ruby Collections (Ruby のコレクションの使用例)
#
# 配列
#
xs = Array.new
xs = [1,2,4,8,16,32]
xs(0)    # => 1 ; 先頭の成分
xs.last # => 32 ; 最後の成分
xs[1..-1] # => [2,4,8,16,32] ; 先頭を除いた部分列
xs.index(8) # => 3 ; 検索
xs.index(9) # => nil; 存在しない
xs.rindex(8) # => 3 ; 逆方向から検索
xs.length # 6 ; 個数
xs.size # 6 ; length と同じ
[1, 2, 3] + [4, 5, 6] # => [1, 2, 3, 4, 5, 6] ; 連結
[1, 2, 3] * 4 # => [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] ; 繰り返し
[1, 2, 3].join('<') # => "1<2<3" ; 各成分を文字列化し,連結
xs.reverse # => [32, 16, 8, 4, 2, 1] ; 逆順
[2,5,1,4,3].sort # => [1, 2, 3, 4, 5] ; 並べ替え
[2,5,1,4,3].sort{|x,y| x <=> y} # => [1, 2, 3, 4, 5] ; 同じ。比較には <=> を使う
[2,5,1,4,3].sort{|x,y| y <=> x} # => [5, 4, 3, 2, 1] ; 逆順
# 参考: <=> は comparator (比較器) と呼ばれるもの
# x > y なら x <=> y は正の整数
# x < y なら x <=> y は負の整数
# x == y なら x <=> は 0 を返す
7 <=> 11 # -1 ; 7 の方が小さい
7 <=> 7 # 0; 等しい
"week" <=> "weak" # => 1 ; 辞書式順序で "week" の方が後
"strong" <=> "stronger" # => -1; 辞書式順序で "strong" の方が前
# 配列自身にも <=> がある。辞書式順序で比較する
[1,2,3,4] <=> [1,2,9,4] # => 1 ; 辞書式順序で [1,2,3,4] の方が前
[1,2,3,4,5] <=> [1,2,3,4] # => -1 ; 辞書式順序で [1,2,3,4,5] の方が後
# 配列の <=> を使うソーティングは,「配列の配列」のソーティングなので混乱しないこと
# push, pop, shift
xs = [1,2,3,4]
xs.push(5) # => [1, 2, 3, 4, 5]; xs の内容も [1, 2, 3, 4, 5] に変更
xs.pop # => 5 ; xs の内容は [1, 2, 3, 4] に変更
xs << 5 # xs.push(5) と同じ
xs.shift # => 1 ; xs からは先頭の成分が除かれる。つまり [2, 3, 4, 5] となる。
# 順列組合せの生成(Enumerator は中身が見えないため to_a で配列に変換)
[1,2,3,4].combination(2).to_a # 4つから2つをとる組合せを列挙
[1,2,3,4].permutation(2).to_a # 4つから2つをとる順列を列挙
[1,2,3].product [4,5] # 直積
[1,2,3].zip [4,5,6] # => [[1, 4], [2, 5], [3, 6]]
# 高階
[1,2,3,4].map{|x| -x } # => [-1, -2, -3, -4]
[1,2,3,4].select{|x| x % 2 == 1 } # => [1, 3]
[1,2,3,4].inject(0){|sum,x| sum + x } # => 10
# (((0 + 1) + 2) + 3) + 4 を計算
# Note:
# 他言語にある内包表記 (List Comprehension) は
# map, select, product, flatten の組合せで実現できる。
# (flatten で引っかかる場合を除く)
#
# inject に相当するものは内包表記では記述できない
#
# 内包表記 + inject で実現できないものは,存在するが,
# 非常に複雑な再帰を使うものに限られる。
# 乱数列
Array.new(3, rand)
# => [0.36016247470384, 0.36016247470384, 0.36016247470384]
# 異なる乱数で初期化するには次のように記述する
Array.new(3){|index| rand}
# => [0.206740544084226, 0.796881324192752, 0.143982524021059]
#
# Hash
#
capital_data = { :Japan => :Tokyo, :France => :Paris, :UK => :London }
# 補足
# コロン (:) で始まる記号は,シンボルといい,intern されている。
# (唯一であることが保証されており,同じリテラルであれば,常に equal? で等しい)
#
# 一般に,ハッシュ表 (Map) のキーは immutable であることが望ましい。
# Ruby において,文字列は mutable でシンボルは immutable であることに注意
# ただし Ruby のハッシュ表のキーの等価性は eql? で判定される。
# 文字列を始め,Ruby の標準ライブラリの eql? は,そのときの内容が等しいかを見る。
# equal? のように,オブジェクト(のアドレス)の等価性を見るのではないので,意味論上の問題は生じない。
# とはいえ,大きな mutable データで eql? 判定をすると時間がかかるので
# ハッシュ表のキーに mutable なデータを用いるのは望ましくないことには変わりない。
capital_data[:Japan] # => :Tokyo
capital_data[:Soviet] # => nil
# エントリーでループ
capital_data.each{|country,capital|
puts country, capital
}
# 上と同じ
capital_data.each{|pair|
puts pair
}
# キーでループ
capital_data.each_key{|country|
puts capital_data[country]
}
# デフォルトの値を定める
capical_data.default = "unknown"
# 配列のハッシュ表やハッシュ表のハッシュ表において,
# 未使用のキーで代入があったとき,そのキーのエントリーを自動的に作る
# Hashtable of Array
h = Hash.new{ |h,k| h[k] = [] }
# Hashtable of Hashtable
h = Hash.new{ |h,k| h[k] = {} }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment