[ENH] PairedCollection class
Richard A. O'Keefe
ok at atlas.otago.ac.nz
Tue Sep 4 00:59:10 UTC 2001
"Lex Spoon" <lex at cc.gatech.edu> wrote:
By the way, there is a nice generalization of the above with:foo:
pattern. It looks like this:
(firstArray with: secondArray) collect: [ :combo | combo first + combo
second ]
This use of #with: (which doesn't currently exist), is identical to ML
and Haskel's "zip" function, and it allows you to use all of collect:,
select:, reject:, do:, detect:, etc. without writing with:collect:,
with:select:, with:reject:, etc. In brief, the presence of a "with"
clause can be orthogonal to which collection operation is being used.
Now it does exist.
Note that it can be combined, so
((a with: b) with: (c with: d)) collect: [:combo |
... combo first first "a" ...
... combo first second "b" ...
... combo second first "c" ...
... combo second second "d" ... ]
gives you iteration over four collections, should you want that.
'From Squeak2.8 of 13 June 2000 [latest update: #2359] on 4 September 2001 at 1:52:50 pm'!
Magnitude subclass: #Pair
instanceVariableNames: 'first second '
classVariableNames: ''
poolDictionaries: ''
category: 'Collections-Support'!
!Pair commentStamp: 'raok 9/4/2001 13:21' prior: 0!
I represent an ordered pair of objects. Pairs exist to support iteration over two or more
collections at once and have no semantics other than aggregation. As a rule, you
should look for a problem-domain abstraction you can use rather than reusing me.
Pair first: x second: y makes a new Pair object.
The obvious accessors are defined.
Comparison is defined as ledxicographic comparison.
My instance variables 'first' and 'second' mean what they sound like.
!
SequenceableCollection subclass: #PairedCollection
instanceVariableNames: 'first second count size '
classVariableNames: ''
poolDictionaries: ''
category: 'Collections-Sequenceable'!
!PairedCollection commentStamp: 'raok 9/4/2001 13:45' prior: 0!
I act like the sequence you would get by doing
a with: b collect: [:x :y | Pair first: x second: y]
except that I do not allocate a new array or ordered collection, nor do I create all
the pairs straight away. I create pairs lazily, as they are needed. That means that
previously generated pairs can be reclaimed by the garbage collector while you are
still traversing me. The essence of a PairedCollection is to delegate accesses to the
collections it is built from, so you are not allowed to change one.
(a with: b) collect: [:aPair| ... aPair first ... aPair second ...]
is like
a with: b collect: [:x :y| ... x ... y ...]!
!Pair methodsFor: 'comparing' stamp: 'raok 9/4/2001 13:25'!
< aPair
first < aPair first ifTrue: [^true].
aPair first < first ifTrue: [^false].
^second < aPair second! !
!Pair methodsFor: 'comparing' stamp: 'raok 9/4/2001 13:24'!
= aPair
self species = aPair species
ifFalse: [^false]
ifTrue: [^first = aPair first and: [second = aPair second]]! !
!Pair methodsFor: 'comparing' stamp: 'raok 9/4/2001 13:26'!
hash
^first hash "quick and dirty"! !
!Pair methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:21'!
first
^first! !
!Pair methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:22'!
first: anObject
first _ anObject! !
!Pair methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:26'!
first: x second: y
first _ x.
second _ y.
! !
!Pair methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:22'!
second
^second! !
!Pair methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:23'!
second: anObject
second _ anObject ! !
!Pair class methodsFor: 'instance creation' stamp: 'raok 9/4/2001 13:28'!
first: x second: y
^self new first: x second: y! !
!SequenceableCollection methodsFor: 'converting' stamp: 'raok 9/4/2001 13:49'!
with: anotherCollection
"answer a new PairedCollection for iteration"
^PairedCollection first: self second: anotherCollection! !
!PairedCollection methodsFor: 'private' stamp: 'raok 9/4/2001 13:44'!
species
"Answer the preferred class for reconstructing the receiver."
^Array! !
!PairedCollection methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:36'!
at: anIndex
^Pair first: (first at: anIndex) second: (second at: anIndex)! !
!PairedCollection methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:36'!
at: anIndex put: anObject
self error: 'a PairdCollection cannot be changed'
! !
!PairedCollection methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:49'!
first: aCollection second: anotherCollection
aCollection size = anotherCollection size
ifFalse: [self error: 'collection sizes must match'].
first _ aCollection.
second _ anotherCollection.
size _ aCollection size.
^self! !
!PairedCollection methodsFor: 'accessing' stamp: 'raok 9/4/2001 13:35'!
size
^size! !
!PairedCollection class methodsFor: 'instance creation' stamp: 'raok 9/4/2001 13:46'!
first: aCollection second: anotherCollection
^self new first: aCollection second: anotherCollection! !
More information about the Squeak-dev
mailing list
|