--- a/SeqColl.st Fri Feb 25 14:03:36 1994 +0100
+++ b/SeqColl.st Fri Feb 25 14:03:58 1994 +0100
@@ -26,7 +26,7 @@
an index. SequenceableCollection is an abstract class - there are no
instances of it in the system.
-$Header: /cvs/stx/stx/libbasic/Attic/SeqColl.st,v 1.8 1994-01-16 03:45:26 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Attic/SeqColl.st,v 1.9 1994-02-25 13:03:42 claus Exp $
written spring 89 by claus
'!
@@ -59,8 +59,9 @@
!
at:index ifAbsent:exceptionBlock
- "return the element at index if valid. If the index is invalid,
- return the result of evaluating the exceptionblock"
+ "return the element at index if valid.
+ If the index is invalid, return the result of evaluating
+ the exceptionblock."
((index < 1) or:[index > self size]) ifTrue:[
^ exceptionBlock value
@@ -68,6 +69,8 @@
^ self at:index
"#(1 2 3) at:4 ifAbsent:['no such index']"
+ "(Dictionary with:(#foo -> #bar)
+ with:(#frob -> #baz)) at:#foobar ifAbsent:['no such index']"
! !
!SequenceableCollection methodsFor:'queries'!
@@ -105,6 +108,7 @@
stop := self size.
stop == (aCollection size) ifFalse:[^false].
+
index := 1.
[index <= stop] whileTrue:[
(self at:index) = (aCollection at:index) ifFalse:[^false].
@@ -149,18 +153,20 @@
|index1 "{ Class: SmallInteger }"
index2 "{ Class: SmallInteger }"
- stop "{ Class: SmallInteger }" |
+ stop "{ Class: SmallInteger }"
+ sz "{ Class: SmallInteger }"|
- (aCollection == self) ifTrue:[^true].
- (aCollection isKindOf:SequenceableCollection) ifFalse:[^false].
+ (aCollection == self) ifTrue:[^ true].
+ (aCollection isKindOf:SequenceableCollection) ifFalse:[^ false].
stop := aCollection size.
- stop > self size ifTrue:[^false].
+ sz := self size.
+ stop > sz ifTrue:[^false].
- index1 := self size.
+ index1 := sz.
index2 := stop.
[index2 > 0] whileTrue:[
- (self at:index1) = (aCollection at:index2) ifFalse:[^false].
+ (self at:index1) = (aCollection at:index2) ifFalse:[^ false].
index1 := index1 - 1.
index2 := index2 - 1
].
@@ -211,10 +217,11 @@
"'abc' , '123'"
"'abc' , #($q $w $e $r $t $y) asSortedCollection"
"'abc' , #(1 2 3 4 5)" "-- will fail, since strings cannot store integers"
+ "'abc' asArray , #(1 2 3 4 5)"
!
copyWith:newElement
- "return a new collection consisting of receivers elements
+ "return a new collection consisting of a copy of the receivers elements
plus the argument."
|newCollection mySize newSize|
@@ -232,10 +239,10 @@
"'abcdefg' copyWith:1" "-- will fail: integer cannot be stored into string"
!
-copyWithout:elementToSkip
- "return a new collection consisting of receivers elements
- without elementToSkip, if it was present. No error is reported,
- if elementToSkip is not in the collection."
+copyWithoutFirst:elementToSkip
+ "return a new collection consisting of a copy of the receivers elements
+ without the first elementToSkip, if it was present.
+ No error is reported, if elementToSkip is not in the collection."
|copy skipIndex sz|
@@ -248,9 +255,76 @@
copy replaceFrom:skipIndex to:(sz - 1) with:self startingAt:(skipIndex + 1).
^ copy
+ "#($a $b $c $d $e $f $g) copyWithoutFirst:$d"
+ "#($a $b $c $d $e $f $g) copyWithoutFirst:$x"
+ "#(90 80 70 60 50) copyWithoutFirst:70"
+ "#(90 80 70 80 60 45 80 50) copyWithoutFirst:80"
+!
+
+copyWithout:elementToSkip
+ "return a new collection consisting of a copy of the receiver, with
+ ALL elements equal to elementToSkip are left out.
+ No error is reported, if elementToSkip is not in the collection."
+
+ |n copy srcIndex dstIndex skipIndex sz l|
+
+ "the code below may look like overkill,
+ however, for big collections its better to move data
+ around in big chunks"
+
+ n := self occurrencesOf:elementToSkip.
+ n == 0 ifTrue:[^ self copy].
+
+ sz := self size.
+ copy := self species new:(sz - n).
+
+ srcIndex := 1.
+ dstIndex := 1.
+
+ n timesRepeat:[
+ skipIndex := self indexOf:elementToSkip startingAt:srcIndex.
+ l := skipIndex - srcIndex.
+ l ~~ 0 ifTrue:[
+ copy replaceFrom:dstIndex to:(dstIndex + l - 1)
+ with:self startingAt:srcIndex.
+ dstIndex := dstIndex + l
+ ].
+ srcIndex := skipIndex + 1
+ ].
+ l := sz - srcIndex.
+ copy replaceFrom:dstIndex to:(dstIndex + l)
+ with:self startingAt:srcIndex.
+ ^ copy
+
"#($a $b $c $d $e $f $g) copyWithout:$d"
+ "#($a $b $c $d $e $f $g) copyWithout:$a"
+ "#($a $b $c $d $e $f $g) copyWithout:$g"
+ "#($a $b $c $a $a $d $e $a $f $g) copyWithout:$a"
"#($a $b $c $d $e $f $g) copyWithout:$x"
- "#(90 80 70 60 50) asSortedCollection copyWithout:70"
+ "#(90 80 70 60 50) copyWithout:70"
+ "#(90 80 70 80 60 45 80 50) copyWithout:80"
+!
+
+copyWithoutIndex:omitIndex
+ "return a new collection consisting of receivers elements
+ without the argument stored at omitIndex"
+
+ |copy sz|
+
+ sz := self size.
+ copy := self species new:(sz - 1).
+ copy replaceFrom:1
+ to:(omitIndex - 1)
+ with:self
+ startingAt:1.
+ copy replaceFrom:omitIndex
+ to:sz - 1
+ with:self
+ startingAt:(omitIndex + 1).
+ ^ copy
+
+ "#(1 2 3 4 5 6 7 8 9 0) copyWithoutIndex:3"
+ "'abcdefghijkl' copyWithoutIndex:5"
!
copyFrom:start to:stop
@@ -260,7 +334,7 @@
|newCollection newSize|
newSize := stop - start + 1.
- newCollection := self class new:newSize.
+ newCollection := self species new:newSize.
newCollection replaceFrom:1 to:newSize with:self startingAt:start.
^ newCollection
@@ -280,7 +354,7 @@
copyTo:stop
"return a new collection consisting of receivers elements
- from 1 up to index stop"
+ from 1 up to (including) index stop"
^ self copyFrom:1 to:stop
@@ -288,21 +362,82 @@
"'1234567890' copyTo:4"
!
-copyWithoutIndex:omitIndex
- "return a new collection consisting of receivers elements
- without the argument stored at omitIndex"
+copyFirst:count
+ "return a new collection consisting of the receivers first count
+ elements - this is just a rename of copyTo: - for compatibility."
+
+ ^ self copyFrom:1 to:count
+
+ "#($a $b $c $d $e $f $g) copyFirst:5"
+ "'1234567890' copyFirst:4"
+!
+
+copyLast:count
+ "return a new collection consisting of the receivers last count
+ elements."
+
+ |sz|
- |copy|
+ sz := self size.
+ ^ self copyFrom:(sz - count + 1) to:sz
+
+ "#($a $b $c $d $e $f $g) copyLast:5"
+ "'1234567890' copyLast:4"
+!
+
+copyUpTo:element
+ "return a new collection consisting of the receiver elements
+ up-to (but excluding) the first occurence of element."
+
+ |idx|
+
+ idx := self indexOf:element.
+ idx == 0 ifTrue:[^ nil]. "question: is this ok?"
+ idx == 1 ifTrue:[^ self species new].
+ ^ self copyFrom:1 to:(idx-1)
- copy := self class new:(self size - 1).
- copy replaceFrom:1 to:(omitIndex - 1) with:self startingAt:1.
- copy replaceFrom:omitIndex to:(copy size)
- with:self startingAt:(omitIndex + 1).
- ^ copy
+ "#($a $b $c $d $e $f $g) copyUpTo:$d"
+ "'1234567890' copyUpTo:$5"
+ "'1234567890' copyUpTo:$a"
+ "'1234567890' copyUpTo:$1"
+!
+
+copyThrough:element
+ "return a new collection consisting of the receiver elements
+ up-to (AND including) the first occurence of element."
+
+ |idx|
+
+ idx := self indexOf:element.
+ idx == 0 ifTrue:[^ nil]. "question: is this ok?"
+ ^ self copyFrom:1 to:idx
- "#(1 2 3 4 5 6 7 8 9 0) copyWithoutIndex:3"
- "'abcdefghijkl' copyWithoutIndex:5"
+ "#($a $b $c $d $e $f $g) copyThrough:$d"
+ "'1234567890' copyThrough:$5"
+ "'1234567890' copyThrough:$a"
+ "'1234567890' copyThrough:$1"
+!
+
+copyReplaceFrom:startIndex to:endIndex with:aCollection
+ "return a copy of the receiver, where the elements from startIndex to
+ endIndex have been replaced by the elements of aCollection"
+
+ |newColl replSize|
+ replSize := aCollection size.
+ newColl := self species new:(self size - (endIndex - startIndex + 1) + replSize).
+ newColl replaceFrom:1 to:(startIndex - 1) with:self.
+ newColl replaceFrom:startIndex with:aCollection.
+ newColl replaceFrom:(startIndex + replSize) with:self startingAt:(endIndex + 1).
+ ^ newColl
+
+ "#(1 2 3 4 5 6 7 8 9 0) copyReplaceFrom:3 to:6 with:#(a b c d e f g h i j k)"
+ "'hello world' copyReplaceFrom:6 to:6 with:' there, '"
+!
+
+copyReplaceAll:startIndex to:endIndex with:aCollection
+ "return a copy of the receiver, where the elements from startIndex to
+ endIndex have been replaced by the elements of aCollection"
! !
!SequenceableCollection methodsFor:'filling and replacing'!
@@ -403,6 +538,9 @@
to:stop
with:replacementCollection
startingAt:1
+
+ "'1234567890' replaceFrom:5 to:7 with:'abcdef'"
+ "#($a $b $c $d $e) replaceFrom:2 to:3 with:'12345'"
!
replaceFrom:start to:stop with:replacementCollection startingAt:repStart
@@ -438,6 +576,24 @@
srcIndex := srcIndex + 1.
dstIndex := dstIndex + 1
]
+
+ "'1234567890' replaceFrom:5 to:7 with:'abcdef' startingAt:3"
+ "#($a $b $c $d $e) replaceFrom:2 to:3 with:'12345' startingAt:4"
+!
+
+startingAt:sourceStart replaceElementsIn:destColl from:destStartIndex to:destEndIndex
+ "replace elements in destColl with elements from the receiver.
+ Notice: This operation modifies the destination collection, NOT a copy;
+ therefore the change may affect all others referencing this object."
+
+ destColl replaceFrom:destStartIndex to:destEndIndex with:self startingAt:sourceStart
+
+ "
+ |s|
+ s := 'abcdefghijklmnop'.
+ '1234567890' startingAt:1 replaceElementsIn:s from:1 to:3.
+ s'123defghijklmnop'
+ "
!
withCRs
@@ -460,33 +616,72 @@
!SequenceableCollection methodsFor:'adding & removing'!
-addFirst:anElement
- "prepend the argument, anElement to the collection."
+addFirst:anObject
+ "prepend the argument, anObject to the collection.
+ Return the argument, anObject.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
|newSize|
newSize := self size + 1.
self grow:newSize.
self replaceFrom:2 to:newSize with:self startingAt:1.
- self at:1 put:anElement
+ self at:1 put:anObject.
+ ^ anObject
- "#(1 2 3 4 5 6 7 8) addFirst:'hello'"
+ "
+ |a|
+ a:= #(1 2 3 4 5 6 7 8).
+ a addFirst:'hello'.
+ a
+ "
+ "
+ |c|
+ c := #(1 2 3 4 5 6 7 8) asOrderedCollection.
+ c addFirst:'hello'.
+ c
+ "
!
-add:anElement
- "append the argument, anElement to the collection"
+add:anObject
+ "append the argument, anObject to the collection.
+ Return the argument, anObject.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
|newSize|
newSize := self size + 1.
self grow:newSize.
- self at:newSize put:anElement
+ self at:newSize put:anObject.
+ ^ anObject
- "#(1 2 3 4 5 6 7 8) add:'hello'"
+ "
+ |a|
+ a := #(1 2 3 4 5 6 7 8).
+ a add:'hello'.
+ a
+ "
+ "
+ |c|
+ c := #(1 2 3 4 5 6 7 8) asOrderedCollection.
+ c add:'hello'.
+ c
+ "
!
add:anElement beforeIndex:index
- "insert the first argument, anObject into the collection before slot index"
+ "insert the first argument, anObject into the collection before slot index.
+ Return the receiver (sigh - ST-80 compatibility).
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
|newSize|
@@ -499,8 +694,12 @@
!
remove:anElement ifAbsent:aBlock
- "search for anElement and, if present remove it; if not present
- return the value of evaluating aBlock"
+ "search for anElement and, if present remove and return it.
+ If not present, return the value of evaluating aBlock.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
|any
dstIndex "{ Class: SmallInteger }"
@@ -520,17 +719,21 @@
]
].
any ifTrue:[
- self grow:dstIndex - 1
- ] ifFalse:[
- aBlock value
- ]
+ self grow:dstIndex - 1.
+ ^ anElement
+ ].
+ ^ aBlock value
"#(1 2 3 4 5 6 7 8 9 0) remove:3 ifAbsent:[Transcript showCr:'no']"
- "#(1 2 3 4 5 6 7 8 9 0) remove:99 ifAbsent:[Transcript showCr:'no']"
+ "#(1 2 3 4 5 6 7 8 9 0) remove:99 ifAbsent:[#oops]"
!
removeFromIndex:startIndex toIndex:endIndex
- "remove the elements stored at indexes between startIndex and endIndex"
+ "remove the elements stored at indexes between startIndex and endIndex.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
|newSize|
@@ -541,12 +744,66 @@
"#(1 2 3 4 5 6 7 8 9 0) removeFromIndex:3 toIndex:5"
!
+removeAtIndex:index
+ "remove the argument stored at index and return it.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
+
+ |element|
+
+ element := self at:index.
+ self removeIndex:index.
+ ^ element
+
+ "#($a $b $c $d $e $f $g) removeAtIndex:3"
+!
+
removeIndex:index
- "remove the argument stored at index"
+ "remove the argument stored at index. Return the receiver.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
self removeFromIndex:index toIndex:index
- "#(1 2 3 4 5 6 7 8 9 0) removeIndex:3"
+ "#($a $b $c $d $e $f $g) removeIndex:3"
+!
+
+removeFirst
+ "remove the first element of the receiver and return it.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
+
+ ^ self removeAtIndex:1
+
+ "
+ |a|
+ a := #(1 2 3 4 5 6).
+ a removeFirst.
+ a
+ "
+!
+
+removeLast
+ "remove the last element of the receiver and return it.
+
+ Notice, that this is modifies the receiver NOT a copy.
+ Also note, that it may be a slow operation for some collections due to the grow:
+ (i.e. for Strings and Arrays it is not recommened)"
+
+ ^ self removeAtIndex:(self size)
+
+ "
+ |a|
+ a := #(1 2 3 4 5 6).
+ a removeLast.
+ a
+ "
! !
!SequenceableCollection methodsFor:'searching'!