シュワルツ(シュウォーツ)変換 (Schwartzian Transform)

コレクションを操作する際に、各要素に変換を行った要素に基づいて操作を行うが、欲しい結果は変換を行った要素のコレクションではなく元の要素のコレクションである場合に利用する。

文字列の配列を大文字・小文字を無視してソートする場合を考える。

# 文字列の配列
ary = ["foo", "Bar", "baz", "HOGE", "FUGA"]

# そのままソートすると
p ary.sort #=> ["Bar", "FUGA", "HOGE", "baz", "foo"]

# 大文字・小文字を無視してソートする(ブロックが繰り返される度に upcase が実行される)
p ary.sort {|x,y| x.upcase <=> y.upcase } #=> ["Bar", "baz", "foo", "FUGA", "HOGE"]

# 大文字・小文字を無視してソートする(upcase した要素と元の要素を含む配列を作り sort した後、元の要素のみを取り出す )
p ary.collect {|x| [x.upcase, x] }.sort.collect {|y| y[-1] } #=> ["Bar", "baz", "foo", "FUGA", "HOGE"]

# ruby に備わっている sort_by メソッドでシュワルツ変換を利用する。
p ary.sort_by {|x| x.upcase } #=> ["Bar", "baz", "foo", "FUGA", "HOGE"]

collect を使って一時配列を作ってソートする場合の一時配列を見てみる。

p ary.collect {|x| [x.upcase, x] }
#=> [["FOO", "foo"], ["BAR", "Bar"], ["BAZ", "baz"], ["HOGE", "HOGE"], ["FUGA", "FUGA"]]
p ary.collect {|x| [x.upcase, x] }.sort
#=> [["BAR", "Bar"], ["BAZ", "baz"], ["FOO", "foo"], ["FUGA", "FUGA"], ["HOGE", "HOGE"]]
p ary.collect {|x| [x.upcase, x] }.sort.collect {|y| y[-1] }
#=> ["Bar", "baz", "foo", "FUGA", "HOGE"]
まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法
まつもとゆきひろ
日経BP出版センター
売り上げランキング: 6604
«
»