mishe
mishe

Reputation: 301

Parsing string in SmallTalk

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

Answers (2)

outis
outis

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 form

amount =: 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 ].

Characters don't respond to +, so you'll need to convert to an Integer and back. Note that since Strings 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

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 236004

Try this:

x := 'costam'
answer := (x asIntegerArray collect: [ :c | c + 1]) asString.
Transcript show: answer

Upvotes: 1

Related Questions