Smalltalkのtは小文字です

id:sumim:about

オブジェクト指向の“モヤッと”の正体を知りたくなったら、id:sumim:20040525:p1id:sumim:20080415:p1 がお役に立つかも…。


 | 

2006-05-18

[][][] 二次元配列の要素を縦方向に足す


技術メモ帳 - 二次元配列を列方向に処理 で、まず読み込みは素直にしておいて、得られた配列が、

ary = [[1,2,3],[4,5,6],[7,8,9]]

だったとして、さあ、そこからどうするか…というのを考えてみました。Ruby には transpose というのがあるので、これを使うのがよさそうです。

ary.transpose.collect{|row| row.inject(0){|s,e| s+e}}  #=> [12, 15, 18]

Enumerable#sum というのがもし Ruby にあったなら、もっと直感的に書けそうですね。(念のため、Smalltalk の Collection >> #sum の定義は、このようにはなっていません。実際に定義をご覧になって、なぜなのかを考えてみるのも面白いでしょう。っても、メソッドのコメントにその“答え”そのものずばりが書いてあるのですが…(^_^;))

module Enumerable
  def sum
    inject(0){|s,e| s+e}
  end
end
ary.transpose.collect{|row| row.sum}

さて。我らが Smalltalk ではどうか?


Ruby と異なり、Smalltalk では Collection >> #+ が対応する各要素の和を要素に持つ配列を返します。(余談ですが、Smalltalk-76 のころまでは Smalltalk も Ruby と同じ仕様でした…)

#Ruby
[1,2,3] + [4,5,6]      #=> [1,2,3,4,5,6]
"Smalltalk"
#(1 2 3) + #(4 5 6)   " => #(5 7 9) "

ちなみに、連結させたいときには、#, という名前のメソッドをレシーバに起動させます。

"Smalltalk"
#(1 2 3) , #(4 5 6)   " => #(1 2 3 4 5 6) "

この #+ の振る舞いを利用すると、Smalltalk で、くだんの処理は #inject:into: を用い、これまた #inject:into: の使い方としてはごくありふれた記述として…、次のように書くことができます。

| array |
array := #((1 2 3) (4 5 6) (7 8 9)).

array inject: #(0 0 0) into: [:sum :each | sum + each]
=> #(12 15 18)

さらに、Smalltalk には #sum がすでにあるので、

#((1 2 3) (4 5 6) (7 8 9)) sum

と書いて済ませてしまうほうがクールでしょう。ただし、ここで起動される #sum は、なにも二次元配列専用のメソッドだというわけではない点に注意してください。

#(1 2 3 4 5 6 7 8 9 10) sum     " => 55 "
{1@1. 2@2. 3@3. 4@4. 5@5} sum   " => 15@15 "

このように普遍的な記述が可能で、もちろんそれに対する期待通りの結果を返してきてくれることの背景には、前述の Collection >> #+ の振る舞いが大きく係わっています。それとからめて Collection >> #+ は、その実装の方法も面白いので、興味のあるかたは是非、定義を見てみてください。「+」を(必要ならタイプして入力後、)選択して、browse it(cmd/alt + b)か、implementors of it(cmd/alt + m)でブラウザが開くので、#+ メソッドの一覧から Collection >> #+ を選べば呼び出せます。

http://squab.no-ip.com:8080/collab/uploads/implementorsofplus.png


いわゆる“ダブルディスパッチ”という手法が使われています。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト

コメントを書くには、なぞなぞ認証に回答する必要があります。

 | 
2004 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 |

最近のコメント

1. 10/02 sumim
2. 10/02 shiro
3. 10/01 sumim
4. 10/01 shiro
5. 10/01 sumim

最近のトラックバック

1. 01/05 no_orz_no_life - Erlangとボウリングの点数とリストのパターンマッ...
2. 12/30 None is None is None - ソニーからの挑戦状をPythonで解いてみた
3. 05/25 プログラマ―ズログ - オブジェクト指向言語が流行した必然性につい...
4. 10/11 プログラマ―ズログ - オブジェクト指向言語が流行した必然性につい...
5. 10/01 cozeの勉強日記 - 素数ジェネレータ

この日記のはてなブックマーク数
1016296