I have a question about converting an OrderedCollection full of chars into a string. [1]
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
String withAll: yourCollection
as in...
String withAll: (#($a $b $c) asOrderedCollection)
On 12/29/12 12:30 PM, Chris Cunnington wrote:
I have a question about converting an OrderedCollection full of chars into a string. [1]
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
The following works:
String withAll: #($a $b $c)
But I'm not sure I'm answering your question.
On Dec 29, 2012, at 09:30 , Chris Cunnington wrote:
I have a question about converting an OrderedCollection full of chars into a string. [1]
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
On Sat, 29 Dec 2012, Chris Cunnington wrote:
I have a question about converting an OrderedCollection full of chars into a string. [1]
| oc | oc := #($a $b $c) asOrderedCollection. oc as: String.
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
Since the size of Strings (or an instance of a variable class in general) can't be changed, therefore creating an empty String and concatenating to it one character at a time is a bad pattern in Smalltalk. Your algorithm will need O(n^2) time to finish (where n is the number of characters), and you'll also waste O(n^2) space, which will make your code even slower, since the intermediate collections will have to be garbage collected.
Levente
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
On 2012-12-29 1:47 PM, Levente Uzonyi wrote:
On Sat, 29 Dec 2012, Chris Cunnington wrote:
I have a question about converting an OrderedCollection full of chars into a string. [1]
| oc | oc := #($a $b $c) asOrderedCollection. oc as: String.
Thanks.
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
Since the size of Strings (or an instance of a variable class in general) can't be changed, therefore creating an empty String and concatenating to it one character at a time is a bad pattern in Smalltalk. Your algorithm will need O(n^2) time to finish (where n is the number of characters), and you'll also waste O(n^2) space, which will make your code even slower, since the intermediate collections will have to be garbage collected.
Levente
I rolled the versions forward and back to try them out. It's much slower concatenating one character at a time. I figured there had to be a better way, but wasn't seeing it.
Thanks, Chris
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
On 29 December 2012 17:30, Chris Cunnington smalltalktelevision@gmail.com wrote:
I have a question about converting an OrderedCollection full of chars into a string. [1]
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
You're getting Characters, I guess, because you're reading one element at a time [1]. There's nothing stopping you reading more than that:
('abc' reading read: 3) = 'abc'. ('abc reading rest) = 'abc'.
frank
[1] It's worth bearing in mind that Xtreams operate over streams of arbitrary objects, not just characters.
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
On 2012-12-29 3:46 PM, Frank Shearar wrote:
On 29 December 2012 17:30, Chris Cunnington smalltalktelevision@gmail.com wrote:
I have a question about converting an OrderedCollection full of chars into a string. [1]
I would have thought there was a method like #asString that could be sent to an OrderedCollection to produce a string. I find myself having to do the process in three steps: 1) #reading the OC; 2) creating an empty string; and then, 3) iterating over every char to put it into the String.
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
You're getting Characters, I guess, because you're reading one element at a time [1]. There's nothing stopping you reading more than that:
('abc' reading read: 3) = 'abc'. ('abc reading rest) = 'abc'.
frank
[1] It's worth bearing in mind that Xtreams operate over streams of arbitrary objects, not just characters.
I don't know. The situation is more like:
oc := #($a $b $c). oc := oc asOrderedCollection. oc reading read: 3 an OrderedCollection($a $b $c)
The terminal is the OC. But it returns an OC and I want a string from the chars. I've been looking at the transforms page of the Xtreams docs and that seems more about changing the encoding. I think my problem wasn't really about Xtreams.
Chris
Chris
[1]
startTag: data <action: 'element'> |tagdata str | tagdata := data second first reading. str := (String new: 20) writing. tagdata do: [:each| str put: each]. ^'html ' , (data first second first asString) , $: , $' , (str close; terminal) , $'
On Sat, Dec 29, 2012 at 12:30 PM, Chris Cunnington < smalltalktelevision@gmail.com> wrote:
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Yeah, writing into an OrderedCollection with a stream is a bit suspect to begin with. Both provide a way to grow an underlying fix-size collection as you add more elements. If you have an OrderedCollection, you can just send #add:, no need for a write stream. If you want to build a string, "String new writing" will do the job, no need for an OrderedCollection.
Also, you can write an OC full of characters directly into a write stream on a string:
chars := 'abc' asOrderedCollection. String new writing write: '123'; write: chars; conclusion
Colin
On 2012-12-30 8:52 AM, Colin Putney wrote:
On Sat, Dec 29, 2012 at 12:30 PM, Chris Cunnington <smalltalktelevision@gmail.com mailto:smalltalktelevision@gmail.com> wrote:
I think I'm missing a simpler way. Especially with Xtreams. Shouldn't I just use a filter, change the #contentSpecies, or something?
Yeah, writing into an OrderedCollection with a stream is a bit suspect to begin with. Both provide a way to grow an underlying fix-size collection as you add more elements. If you have an OrderedCollection, you can just send #add:, no need for a write stream. If you want to build a string, "String new writing" will do the job, no need for an OrderedCollection.
Also, you can write an OC full of characters directly into a write stream on a string:
chars := 'abc' asOrderedCollection. String new writing write: '123'; write: chars; conclusion
Colin
Martin also made it look easier with a write than a read. I think I was looking at it the wrong way around. The OC shouldn't be the receiver but the argument. #writing into a String instead of #reading an OC.
Thanks, Chris
squeak-dev@lists.squeakfoundation.org