Smalltalk problem for someone - extract firstname,lastnames

The issue is to extract the firstname and lastNames from a string called fullname.

e.g. fullname of "michael john horatio bassett" -> firstname "michael" and lastnames "john horatio bassett"

Below is the code that got the job done in the short time I had, but its not a Smalltalk solution. if anyone would like to post Smalltalkish solutions that would be great.

Referring to the code below, I expect there is an easy way of taking off the first word from "fullname" and the remainder will be the lastName. Personally, what I would also really like to know is how to elegantly build the lastName string from the "names" array.

       "extract first name and last name from name token"
       names := fullname tokenize: ' '.
       firstName := names at: 1.
       lastName := ''.
       (names size > 1) ifTrue: [
               lastNames := names copyFrom: 2 to: (names size) -1.
               lastNames do: [ :ln |
                       lastName := lastName,ln,' ' ].
               lastName := lastName,(names at: names size) ].
       Transcript showCr: firstName,' : ',lastName.


I wouldn't know if this is a Smalltalkish solution,; just a different way :)

       tokens:='michael john horatio basset' subStrings.
       firstName := tokens first.
       lastName := String
                               streamContents: [:stream | tokens allButFirst
                                               do: [:token | stream nextPutAll: token]
                                               separatedBy: [stream nextPutAll: ' ']].
       Transcript show: firstName.
       Transcript show: lastName

The stream solution is very nice. Alternatively, this is one based on tokenization:

names := fullname subStrings.
firstName := names first.
lastNames := names allButFirst join: ' '

(kudos to Stephen Compall for introducing #join:).

Other ways to improve the procedural solution in the post would be to use a Stream to compose the lastName, as well as #do:separatedBy:

I see we were on the same path :)

I hadn't thought of #streamContents: in fact. Bravo ;-)

Thank you everyone who answered - I've enjoyed the responses and the insights.

why not just:

 names := fullname readStream.
 firstName := names upTo: ' '.
 lastName := names upToEnd.

This solution did not work for me as is.

The result of Character space, or the literal $ , needs to be
passed to #upTo: to get the first name correctly.

Thanks - very nice.

User login