challenge コレクションの実装

コレクションフレームワークに則ってコレクションクラスを実装して下さい.

具体的にどのようなコレクションを実装しても構いませんが,コレクションフレームワークで用意された基本的なメソッドは一通り呼べるようにして下さい. foreach系の構文があれば,それでも使えるとよいです.

例えば,Rubyであれば以下のようなコードで(mapを直接定義することなく)要素を列挙できる必要があるでしょう.

1
2
3
4
5
6
p MyCollection.new.map {|i| i }

# for でも使える
for i in MyCollection.new
  p i
end

Posted feedbacks - Nested

Flatten Hidden

Squeak Smalltalkでは、Collectionクラスを継承し、#add: #do: #remove:ifAbsent: #atRandom: を再定義することで、要求されるインターフェイスを満たす新たなコレクションクラスを設けることが可能です。

Bagクラスの定義が参考になるでしょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Collection subclass: #MyCollection
   instanceVariableNames: 'contents'

MyCollection >> add: element
   ^contents add: element

MyCollection >> do: aBlock
   contents do: [:each | aBlock value: each]

MyCollection >> remove: element ifAbsent: aBlock
   ^contents remove: element ifAbsent: [aBlock value]

MyCollection >> atRandom: aGenerator
   ^contents atRandom: aGenerator

MyCollection >> setContents: newContents
   contents := newContents

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "

MyCollection class >> new
   ^self new: 1

MyCollection class >> new: numElements
   ^super new setContents: (OrderedCollection new: numElements); yourself

MyCollection class >> newFrom: aCollection
   ^self withAll: aCollection

MyCollection class >> example
   | myCollection |
   myCollection := MyCollection newFrom: #(4 3 2 1).   "=> a MyCollection(4 3 2 1) "
   myCollection collect: [:each | each * 2].           "=> a MyCollection(8 6 4 2) "
   myCollection select: [:each | each even].           "=> a MyCollection(4 2) "
   myCollection max.                                   "=> 4 "
   myCollection * 2.                                   "=> a MyCollection(8 6 4 2) "
   myCollection atRandom                               "=> 3 "

書き忘れましたが、新しく定義したコレクションについて collection + 2 のような処理ができるのは当然として、Smalltalk の場合、さらに、2 + collection のように交換した場合も評価可能になります。これって、今回の拡張とは全然関係のない 2(が属するクラス SmallInteger)の #+ というメソッドをコールする…というオブジェクト指向の仕組みのことを考えるとちょっと不思議で面白い機能だと思いませんか?

拡張に対するこのような柔軟性は、有名な「ダブルディスパッチ」という仕組みにより実現されています。

1
2
3
4
| myCollection |
myCollection := MyCollection newFrom: (1 to: 3).   "=> a MyCollection(1 2 3) "
myCollection + 2.                                  "=> a MyCollection(3 4 5) "
2 + myCollection.                                  "=> a MyCollection(3 4 5) "

Index

Feed

Other

Link

Pathtraq

loading...