From: しん <dezawa / aliadne.net> Subject: [ruby-list:45067] Re: uniq -c みたいなことはできないか Date: Mon, 16 Jun 2008 15:19:58 +0900 > Array#uniq があります。 Array#uniqはUnixのuniqコマンドとは違う挙動をするので注意! > 5> Hash.new(0).tap{|cnt| ary.each{|e| cnt[e]+=1 }} # => {1=>3, 2=>4, 3=>3} > 6> ary.count(2) # => 4 > > 1〜4 はわかりましたが、5,6 で躓きました。 > tap に秘密がありそう。 Object#tapはレシーバにブロックを作用させて自分自身を返すだけのメソッドです。 class Object def tap yield(self) self end end 以下をどうぞ。 http://d.hatena.ne.jp/rubikitch/20080502/tap http://d.hatena.ne.jp/rubikitch/20080506/1210018999 Enumerable#countは引数で指定された要素を数えます。 ブロックで指定した条件を満たす要素を数えることもできます。 (リファレンスマニュアルにはまだ書いてないが)引数なしで使ったら要素数を返すので、 配列に適用したらArray#lengthと同じ効果です。 --- count(item) -> Integer --- count {| obj | block } -> Integer Returns the number of items in enum for which equals to item. If a block is given, counts the number of elements yielding a true value. ary = [1, 2, 4, 2] ary.count(2) # => 2 ary.count{|x|x%2==0} # => 3 > # http://www.ruby-lang.org/ja/man にもまだ tap, group_by 共に > # 載っていない様ですね。 新しいリファレンスマニュアル…通称「るりま」をどうぞ。 http://doc.loveruby.net/wiki/ http://d.hatena.ne.jp/rubikitch/20080508/ruby187 にRuby 1.8.7で使えるメソッドを実例とともにまとめています。 > ary が配列の配列だったときに > ary.group_by{|e| e[1] } > 見たいにできるのですよね? もちろん。 配列の配列のときは以下のように多重代入式ブロック引数を使うほうが読みやすくなるでしょう。 http://d.hatena.ne.jp/rubikitch/20080302/1204464916 をどうぞ。 ary = [ [1,2], [6,3], [1,8], [7,9] ] ary.group_by {|a| a[0] + a[1] } # => {3=>[[1, 2]], 9=>[[6, 3], [1, 8]], 16=>[[7, 9]]} ary.group_by {|a,b| a + b } # ブロック引数の代入は多重代入のルールで # => {3=>[[1, 2]], 9=>[[6, 3], [1, 8]], 16=>[[7, 9]]} ary.group_by {|a,b| a * b } # => {2=>[[1, 2]], 18=>[[6, 3]], 8=>[[1, 8]], 63=>[[7, 9]]} -- rubikitch Blog: http://d.hatena.ne.jp/rubikitch/ Site: http://www.rubyist.net/~rubikitch/