http://blogs.yahoo.co.jp/takutakutakutaku50/28887753.html
遅レス。 経由で。リンク先の ささださんの inject、sort_by を使った版を直訳ぎみに Squeak の Smalltalk で。
| ss | ((ss := #(○ ○ ○ △ △ ×)) inject: Dictionary new into: [:result :aa | ss do: [:bb | | key | key := {aa. bb} copy sort. result at: key put: (result at: key ifAbsent: [0]) + 1]; yourself]) associations sortBy: [:aa :bb | aa value > bb value]
Ruby の Hash は、Smalltalk では Dictionary に(ほぼ)相当。ただ、Hash.new(0) みたいなサービスはないので、指定したキーが見つからなかったタイミング(#at:ifAbsent: 起動時)で同種の処理をしています。Ruby の inject は、(少なくとも名前は)そもそも Smalltalk の #inject:into: が元なので問題なし。sort_by による シュワルツ変換については、見た目だけが似ているw通常の条件付き並べ替えでごまかしていますので、あしからず。
もっとも、Squeak の Smalltalk には、この局面にぴったりな「重複を許す組み合わせ」が、ファウラーいうところの いささか冗長な ヒューメインなw“コレクションクロージャメソッド”として用意されていますし(#asDigitsToPower:do: などという、ぱっと見、それとはわかりにくい名前でではありますが…)、また、要素を数え上げる場面で便利に使える a Bag もあるので、次のように書いた方が簡単です。
| bag | bag := Bag new. #(○ ○ ○ △ △ ×) asDigitsToPower: 2 do: [:pair | bag add: pair copy sort]. ^ bag sortedCounts asArray
#(12->#(#△ #○) 9->#(#○ #○) 6->#(#× #○) 4->#(#× #△) 4->#(#△ #△) 1->#(#× #×))
余談ですが、こういうとき Squeak の Smalltalk では、オブジェクトの copy を忘れて、けっこう痛い目を見ることがあるので、要注意ですね。