--- a/SequenceableCollection.st Mon Apr 18 21:54:23 2005 +0200
+++ b/SequenceableCollection.st Tue Apr 19 11:05:46 2005 +0200
@@ -1692,6 +1692,146 @@
!SequenceableCollection methodsFor:'converting'!
+asCollectionOfSubCollectionsSeparatedBy:anElement
+ "return a collection containing the subcollections (separated by anElement)
+ of the receiver. If anElement occurs multiple times in a row,
+ the result will contain empty collections.
+ This algorithm uses equality-compare to detect the element."
+
+ |cols myClass
+ numberOfCols "{ Class:SmallInteger }"
+ startIndex "{ Class:SmallInteger }"
+ stopIndex "{ Class:SmallInteger }" |
+
+ "
+ count first, to avoid regrowing of the OC
+ "
+ numberOfCols := (self occurrencesOf:anElement) + 1.
+ cols := OrderedCollection new:numberOfCols.
+ myClass := self species.
+
+ startIndex := 1.
+ 1 to:numberOfCols do:[:lineNr |
+ stopIndex := self indexOf:anElement startingAt:startIndex.
+ stopIndex == 0 ifTrue:[
+ stopIndex := self size
+ ] ifFalse: [
+ stopIndex := stopIndex - 1.
+ ].
+
+ (stopIndex < startIndex) ifTrue: [
+ cols add:(myClass new:0)
+ ] ifFalse: [
+ cols add:(self copyFrom:startIndex to:stopIndex)
+ ].
+ startIndex := stopIndex + 2
+ ].
+ ^ cols
+
+ "
+ '1 one:2 two:3 three:4 four:5 five' withCRs asCollectionOfSubCollectionsSeparatedBy:$:
+ '1 one 2 two 3 three 4 four 5 five' withCRs asCollectionOfSubCollectionsSeparatedBy:Character space
+ #(a b c d e f g h) asCollectionOfSubCollectionsSeparatedBy: #d.
+ #(a b c d e f d d g h) asCollectionOfSubCollectionsSeparatedBy: #d.
+ "
+!
+
+asCollectionOfSubCollectionsSeparatedByAll:aSeparatorCollection
+ "return a collection containing the subcollections (separated by aSeparatorCollection)
+ of the receiver. If aSeparatorCollection occurs multiple times in a row,
+ the result will contain empty strings.
+ Uses equality-compare when searching for aSeparatorCollection."
+
+ |items done myClass
+ startIndex "{ Class:SmallInteger }"
+ stopIndex "{ Class:SmallInteger }" |
+
+ items := OrderedCollection new.
+ myClass := self species.
+
+ startIndex := 1.
+ done := false.
+ [done] whileFalse:[
+ stopIndex := self indexOfSubCollection:aSeparatorCollection startingAt:startIndex.
+ stopIndex == 0 ifTrue:[
+ stopIndex := self size.
+ done := true.
+ ] ifFalse: [
+ stopIndex := stopIndex - 1.
+ ].
+
+ (stopIndex < startIndex) ifTrue: [
+ items add:(myClass new:0)
+ ] ifFalse: [
+ items add:(self copyFrom:startIndex to:stopIndex)
+ ].
+ startIndex := stopIndex + (aSeparatorCollection size) + 1.
+ ].
+ ^ items
+
+ "
+ '1::2::3::4::5::' asCollectionOfSubCollectionsSeparatedByAll:'::'
+ #(1 2 3 1 2 3 4 3 1 1 2 3 1 4 5) asCollectionOfSubCollectionsSeparatedByAll:#(3 1)
+ "
+!
+
+asCollectionOfSubCollectionsSeparatedByAny:aCollectionOfSeparators
+ "return a collection containing the subCollection
+ (separated by any from aCollectionOfSeparators) of the receiver.
+ This allows breaking up strings using a number of elements as separator.
+ Uses equality-compare when searching for separators."
+
+ ^ self asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:el | aCollectionOfSeparators includes:el]
+
+ "
+ 'hello:world:isnt:this nice' asCollectionOfSubCollectionsSeparatedByAny:#($:)
+ 'hello:world:isnt:this nice' asCollectionOfSubCollectionsSeparatedByAny:':'
+ 'hello:world:isnt:this nice' asCollectionOfSubCollectionsSeparatedByAny:(Array with:$: with:Character space)
+ 'hello:world:isnt:this nice' asCollectionOfSubCollectionsSeparatedByAny:': '
+ 'h1e2l3l4o' asCollectionOfSubCollectionsSeparatedByAny:($1 to: $9)
+ #(1 9 2 8 3 7 4 6 5 5) asCollectionOfSubCollectionsSeparatedByAny:#(1 2 3)
+ "
+!
+
+asCollectionOfSubCollectionsSeparatedByAnyForWhich:aBlock
+ "return a collection containing the subCollection
+ (separated by elements for which aBlock evaluates to true) of the receiver.
+ This allows breaking up strings using an arbitrary condition."
+
+ |words
+ start "{ Class:SmallInteger }"
+ stop "{ Class:SmallInteger }"
+ mySize "{ Class:SmallInteger }"|
+
+ words := OrderedCollection new.
+ start := 1.
+ mySize := self size.
+ [start <= mySize] whileTrue:[
+ "skip multiple separators"
+ [ aBlock value:(self at:start)] whileTrue:[
+ start := start + 1 .
+ start > mySize ifTrue:[
+ ^ words
+ ].
+ ].
+
+ stop := self findFirst:aBlock startingAt:start.
+ stop == 0 ifTrue:[
+ words add:(self copyFrom:start to:mySize).
+ ^ words
+ ].
+ words add:(self copyFrom:start to:(stop - 1)).
+ start := stop
+ ].
+ ^ words
+
+ "
+ 'hello:world:isnt:this nice' asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:ch | ch = $:]
+ 'h1e2l3l4o' asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:ch | ch isDigit]
+ #(1 9 2 8 3 7 4 6 5 5) asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:n | n odd]
+ "
+!
+
asSequenceableCollection
"return myself as a SequenceableCollection.
I am already a SequenceableCollection."
@@ -6671,7 +6811,7 @@
!SequenceableCollection class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/SequenceableCollection.st,v 1.221 2005-04-08 22:55:22 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/SequenceableCollection.st,v 1.222 2005-04-19 09:05:46 cg Exp $'
! !
SequenceableCollection initialize!