From: Yukihiro Matsumoto Date: 2007-02-26T12:21:59+09:00 Subject: [ruby-dev:30423] Re: Arrayのメソッド増強について まつもと ゆきひろです In message "Re: [ruby-dev:30407] Arrayのメソッド増強について" on Sat, 24 Feb 2007 14:21:37 +0900, Minero Aoki writes: |1.9 で String#each がなくなりましたが、どうにも不便です。 |なんで不便なのか考えてみたところ、Array のメソッドが |String に比べて弱いのが原因ではないかと考えるようになり |ました。そこで、以下のようなメソッドを新たに導入する |ことを提案します。 仕様が簡単で、名前も納得できたtakeとdropは早速trunkに取り込 みます。残りはもうちょっと考えましょう。 |--- Enumerable#split(max = nil) {|item| .... } | |each で得られる要素を順番にブロックに渡し、ブロックが |真を返したところで分割して、配列の配列を返す。最大 max |個まで分割する。max = nil のときは無制限に分割する。 |(非破壊的) | |例 | p [1, 2, 3, 4, 5].split {|i| i % 2 == 0 } #=> [[1], [3], [5]] | |他の言語での例: Haskellのbreakを繰り返し適用する場 |合に相当 String#splitとの類推が効くという話ではありますが、逆に引数パ ターンがちょっと違うので混乱しそうな気もします。Stringはもう Enumerableをincludeしていないので問題ないのかな? |--- Enumerable#span {|item| ... } | |配列の要素のうちブロックが真を返す先頭部分と残りの部分に |分割して 2 要素の配列で返す。(非破壊的) | |例 | p [1, 2, 3, 1, 2, 3].span {|item| item < 3 } # => [[1, 2], [3, |1, 2, 3]] | |他の言語での例: Haskellのspan 個人的にはこの動作にspanという名前は違和感があるのですが。 Haskellが採用しているなら問題ないのかな? |--- Array#take {|item| .... } 別名案:take_while, slice{} | |配列の要素のうちブロックが真を返す要素を先頭から |すべて集めて配列で返す。(非破壊的) | |例 | p [1, 2, 3, 2, 1].take {|i| i < 3 } # => [1, 2] | |他の言語での例: HaskellのtakeWhile ary.take(n) # 最初のn要素 ary.take{|x| cond(x)} # 上記の仕様 で実装しました。近いうちに(今日中?)コミットします。 |--- Array#drop {|item| .... } 別名案:lstrip, drop_while, |reject_head | |配列の要素のうちブロックが真を返す要素を先頭から |すべて除いた残りの配列を返す。(非破壊的) | |例 | p [1, 2, 3, 4, 5].drop {|i| i < 3 } # => [3, 4, 5] | |他の言語での例: HaskellのdropWhile takeと同様。このメソッドはgeneratorを使うなどして遅延評価で きたらいいなあと夢想しないでもないですが。 |--- Array#reverse_drop {|item| .... } 別名案:rstrip, |reject_tail, reject_last | |配列の要素のうちブロックが真を返す要素を末尾から |すべて除いた残りの配列を返す。(非破壊的) | |例 | p [1, 2, 3, 4, 5].reverse_drop {|i| i > 3 } # => [1, 2, 3] 名前に違和感があります。String#rindexからの類推だとrdropなん ですが...。 |--- Array#drop_both {|item| .... } 別名案:strip | |配列の要素のうちブロックが真を返す要素を先頭と末尾の |両方からすべて除いた残りの配列を返す。(非破壊的) | |例 | p [1, 2, 3, 4, 3, 2, 1].drop_both {|i| i < 3 } # => [3, 4, 3] これも名前が。stripってのも分かるような分からないような。 まつもと ゆきひろ /:|)