help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [PATCH] Add #join: and #join:separatedBy:


From: Paolo Bonzini
Subject: [Help-smalltalk] [PATCH] Add #join: and #join:separatedBy:
Date: Thu, 06 Sep 2007 11:00:33 +0200
User-agent: Thunderbird 2.0.0.6 (Macintosh/20070728)

Respectively, instance- and class-side. The latter does not work with any Collections, only Sequenceable ones because it does not make much sense to add a separator if it can end up anywhere else.

This was on my list for a while. It conflicts with Stephen's original implementation of #join: taking a class, but it matches other languages:

  irb(main):004:0> ['abc','def'].join
  => "abcdef"
  irb(main):005:0> ['abc','def'].join(' ')
  => "abc def"

  st> #('abc' 'def') join
  'abcdef'
  st> #('abc' 'def') join: ' '
  'abc def'

Paolo
--- orig/kernel/ArrayColl.st
+++ mod/kernel/ArrayColl.st
@@ -130,6 +130,26 @@ join: aCollection
        newInst replaceFrom: start to: (start := start + subColl size) - 1
                with: subColl].
     ^newInst
+!
+
+join: aCollection separatedBy: sepCollection
+    "Where aCollection is a collection of SequenceableCollections,
+     answer a new instance with all the elements therein, in order,
+     each separated by an occurrence of sepCollection."
+    | newInst start |
+    newInst := self new: (aCollection
+       inject: sepCollection size * (aCollection size - 1)
+       into: [:size :each | size + each size]).
+
+    start := 1.
+    aCollection
+       do: [:subColl |
+           newInst replaceFrom: start to: (start := start + subColl size) - 1
+               with: subColl]
+       separatedBy: [
+           newInst replaceFrom: start to: (start := start + sepCollection 
size) - 1
+               with: sepCollection].
+    ^newInst
 ! !
 
 


--- orig/kernel/SeqCollect.st
+++ mod/kernel/SeqCollect.st
@@ -55,6 +55,21 @@ streamContents: aBlock
     stream truncate.
     aBlock value: stream.
     ^stream contents
+!
+
+join: aCollection separatedBy: sepCollection
+    "Where aCollection is a collection of SequenceableCollections,
+     answer a new instance with all the elements therein, in order,
+     each separated by an occurrence of sepCollection."
+    | newInst start |
+    newInst := self new: (aCollection
+       inject: sepCollection size * (aCollection size - 1)
+       into: [:size :each | size + each size]).
+
+    aCollection
+       do: [:subColl | newInst addAll: subColl]
+       separatedBy: [ newInst addAll: sepCollection].
+    ^newInst
 ! !
 
 
@@ -596,6 +611,21 @@ join
      #('hello, ' 'world') join => 'hello, world'"
     ^self isEmpty ifTrue: [#()]
                  ifFalse: [self first species join: self]
+!
+
+join: sepCollection
+    "Answer a new collection like my first element, with all the
+     elements (in order) of all my elements (which should be
+     collections) separated by sepCollection.
+
+     I use my first element instead of myself as a prototype because
+     my elements are more likely to share the desired properties than
+     I am, such as in:
+
+     #('hello,' 'world') join: ' ' => 'hello, world'"
+    ^self isEmpty
+       ifTrue: [#()]
+       ifFalse: [self first species join: self separatedBy: sepCollection]
 ! !
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]