#FEATURE by stefan
authorStefan Vogel <sv@exept.de>
Wed, 20 Sep 2017 19:18:58 +0200
changeset 22273 50bab26735a7
parent 22272 ac4a1dcf494c
child 22274 ed88bf014cb3
#FEATURE by stefan class: SequenceableCollection added: #asCollectionOfSubCollectionsSeparatedByAll:do: #asCollectionOfSubCollectionsSeparatedByAnyForWhich:do:
SequenceableCollection.st
--- 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.