Reputation: 276
I would like to create a test string from Unicode code points
Something like this
65 asCharacter asString,
66 asCharacter asString,
67 asCharacter asString,
65 asCharacter asString,
769 asCharacter asString
Or
String with: 65 asCharacter
with: 66 asCharacter
with: 67 asCharacter
with: 65 asCharacter
with: 769 asCharacter
This works but
I am looking for a way to convert an array of integer values to an instance of class String.
#(65 66 67 65 769)
Is there a built in method for this? I am looking for an answer like this What is the correct way to test Unicode support in a Smalltalk implementation? one, but for Strings.
Upvotes: 4
Views: 254
Reputation: 9382
Please, consider the following as awfully hackish, undocumented, unsupported and thus absolutely wrong way to do it!
You would think that you cannot mix characters and integers that easily, err you can:
'' asWideString copyReplaceFrom: 1 to: 0 with: (#(65 66 67 65 769) as: WordArray).
Indeed, this goes thru a primitive that doesn't really check for the class, but just for the fact that both receiver and argument are VariableWord classes...
For the very same reason (depending on WriteStream implementation - let's say fragile) this can work:
^'' asWideString writeStream
nextPutAll: (#(65 66 67 65 769) as: WordArray);
contents
The same apply to ByteString and ByteArray.
And of course, in the same vein, let's not forget the most convoluted way to do it, BitBlt:
^((BitBlt toForm: (Form new hackBits: (WideString new: 5)))
sourceForm: (Form new hackBits: (#(65 66 67 65 769) as: WordArray));
combinationRule: Form over;
copyBits;
destForm) bits
We again exploit the WordArray nature of WideString to serve as the container for the bits of a Form (a bitmap).
Hopefully this answer won't get too many votes, it doesn't deserve it!
Upvotes: 1
Reputation: 14858
Here is a "low level" variant:
codepoints := #(65 66 67 65 769).
string := WideString new: codepoints size.
codepoints withIndexDo: [:cp :i | string wordAt: i put: cp].
^string
Upvotes: 1
Reputation: 10217
Many ways
1. #streamContents:
Use stream if you are doing larger string concatenation/building as it is faster. If just concatenating couple of strings use whatever is more readable.
String streamContents: [ :aStream |
#(65 66 67 65 769) do: [ :each |
aStream nextPut: each asCharacter
]
]
or
String streamContents: [ :aStream |
aStream nextPutAll: (#(65 66 67 65 769) collect: #asCharacter)
]
2. #withAll:
String withAll: (#(65 66 67 65 769) collect: #asCharacter)
3. #collect:as: String
#(65 66 67 65 769) collect: #asCharacter as: String
4. #joinUsing: the characters
(#(65 66 67 65 769) collect: #asCharacter) joinUsing: ''
Note:
At least in Pharo you can use either [ :each | each selector ]
, or just simply #selector
. I find the latter more readable for simple things, but that may be personal preference.
Upvotes: 8
Reputation: 276
Construct the String instance with #withAll:
String withAll:
(#(65 66 67 65 769) collect: [:codepoint | codepoint asCharacter])
Upvotes: 4