#FEATURE by stefan
class: SequenceableCollection
added:
#asCollectionOfSubCollectionsSeparatedByAll:do:
#asCollectionOfSubCollectionsSeparatedByAnyForWhich:do:
--- a/SequenceableCollection.st Tue Sep 19 16:40:03 2017 +0200
+++ b/SequenceableCollection.st Wed Sep 20 19:18:58 2017 +0200
@@ -432,6 +432,7 @@
^ self == SequenceableCollection
! !
+
!SequenceableCollection methodsFor:'Compatibility-Squeak'!
allButFirst
@@ -744,6 +745,7 @@
^ self replaceFrom:start to:stop with:anArray startingAt:repStart
! !
+
!SequenceableCollection methodsFor:'accessing'!
after:anObject
@@ -7183,6 +7185,7 @@
"Created: 14.2.1997 / 16:13:03 / cg"
! !
+
!SequenceableCollection methodsFor:'searching'!
detect:aBlock startingAt:startIndex
@@ -9777,6 +9780,52 @@
"Modified (comment): / 24-01-2017 / 18:57:03 / stefan"
!
+asCollectionOfSubCollectionsSeparatedByAll:aSeparatorCollection do:aBlock
+ "evaluate aBlock for each subcollection generated by separating elements
+ of the receiver by aSeparatorCollection.
+ 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 := self speciesForSubcollection new.
+ myClass := self species.
+
+ startIndex := 1.
+ done := false.
+ [done] whileFalse:[
+ |subCollection|
+
+ stopIndex := self indexOfSubCollection:aSeparatorCollection startingAt:startIndex.
+ stopIndex == 0 ifTrue:[
+ stopIndex := self size.
+ done := true.
+ ] ifFalse: [
+ stopIndex := stopIndex - 1.
+ ].
+
+ (stopIndex < startIndex) ifTrue: [
+ subCollection := myClass new:0.
+ ] ifFalse: [
+ subCollection := self copyFrom:startIndex to:stopIndex.
+ ].
+ aBlock value:subCollection.
+ 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)
+ 'hello+#world+#here' asCollectionOfSubCollectionsSeparatedByAll:'+#'
+ "
+
+ "Created: / 20-09-2017 / 18:58:11 / stefan"
+!
+
asCollectionOfSubCollectionsSeparatedByAny:aCollectionOfSeparators
"return a collection containing the subCollection
(separated by any from aCollectionOfSeparators) of the receiver.
@@ -9870,6 +9919,46 @@
"Modified (format): / 24-01-2017 / 18:57:57 / stefan"
!
+asCollectionOfSubCollectionsSeparatedByAnyForWhich:aCheckBlock do:aBlock
+ "evaluate aBlock for each subcollection generated by separating elements
+ by elements for which aCheckBlock 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 := self speciesForSubcollection new.
+ start := 1.
+ mySize := self size.
+ [start <= mySize] whileTrue:[
+ "skip multiple separators"
+ [ aCheckBlock value:(self at:start)] whileTrue:[
+ start := start + 1 .
+ start > mySize ifTrue:[
+ ^ self
+ ].
+ ].
+
+ stop := self findFirst:aCheckBlock startingAt:start.
+ stop == 0 ifTrue:[
+ aBlock value:(self copyFrom:start to:mySize).
+ ^ self
+ ].
+ aBlock value:(self copyFrom:start to:(stop - 1)).
+ start := stop
+ ].
+
+ "
+ 'hello:world:isnt:this nice' asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:ch | ch = $:] do:[:component| Transcript showCR:component]
+ 'h1e2l3l4o' asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:ch | ch isDigit] do:[:component| Transcript showCR:component]
+ #(1 9 2 8 3 7 4 6 5 5) asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:n | n odd] do:[:component| Transcript showCR:component]
+ "
+
+ "Created: / 20-09-2017 / 19:03:35 / stefan"
+!
+
asStringWith:sepCharOrString
"return a string generated by concatenating my elements
(which must be strings or nil) and embedding sepCharOrString characters in between.