Reputation: 301
what am I trying is to switch each character in string with one next ( a-> b, y -> z, etc). Not sure though how do I do that in Smalltalk and tried to combine like that:
x := 'costam'.
y := x asArray.
y do: [:charr | charr := charr + 1. ].
y do: [:char | Transcript show: char printString; cr].
What I do is: iterate over array and increase each character.. though it doesn't work. I get error: attempt to store into argument. How do I get around that and do it proper way?
Now I got something like this:
x := 'costam'.
y := x asArray.
b := y at: 2.
n := 1.
m := 5.
[ n < m ] whileTrue: [
n := n + 1.
y at: n put: 'a'.
Transcript show: (y printString).
].
Problem that remains is how do I 'increase' characters like a -> b g -> h etc? SOLVED
Upvotes: 4
Views: 3534
Reputation: 77400
From "Smalltalk-80":
Since argument names are pseudo-variable names, they can be used to access values like variable names, but their values cannot be changed by assignment. In the method for
spend:for:
, a statement of the formamount =: amount * taxRate
would be syntactically illegal since the value of amount cannot be reassigned.
You can use the collect:
message to create a new collection:
z =: y collect: [:char | (ch asciiValue + 1) asCharacter ].
Character
s don't respond to +
, so you'll need to convert to an Integer
and back. Note that since String
s are collections, they also respond to collect:
x collect: [:ch | (ch asciiValue + 1) asCharacter ]
If you want only ASCII characters, take the remainder modulo 128 before converting back to a character.
x collect: [:ch | (ch asciiValue + 1 \\ 128) asCharacter ]
If you wish to increment only letters and not other characters, add a conditional to the block.
x collect: [:ch | ch isLetter
ifTrue: [(ch asciiValue + 1) asCharacter]
ifFalse: [ch] ]
Note that the last block doesn't handle letters at the end of a contiguous range (e.g. $z
, or, if the interpreter supports extended ASCII or Unicode, $<16rD6>
), as the exact method depends on the capabilities of the system (basically, what's considered a letter).
Upvotes: 2
Reputation: 236004
Try this:
x := 'costam'
answer := (x asIntegerArray collect: [ :c | c + 1]) asString.
Transcript show: answer
Upvotes: 1