# Swap first and last names in a list

Edited to fix an inconsistency in the given example data format.

I'm trying to write a simple function to load in a csv list of names which is formatted as "Lastname Firstname Initial " and convert it to "Firstname Lastname".

The following code works:

data = Import["class roll.csv", "CSV"]
names = StringCases[StringTrim@data, LetterCharacter ..][[;; , {2, 1}]]
names = StringJoin[#[[1]], " ", #[[2]]] & /@ names


but it feels a lot like a non-Mathematica type of way, i.e. I'm trying to break my old programming habits and learn how to implement this in more "native" Mathematica way.

If you have any suggestions, alternatives, more efficient ways, ... you'd like to share that'd be much appreciated.

Additional info in response to Ajasja's comment, the example data looks like:

ImportString["
lastname1 firstname2 Ii
lastname2 first2 Ii
lastna3 longfirstname2 Ii
", "CSV"]


the last/first/initials are separated by a space, and each line is padded with spaces to get it to an equal (but large) width.

P.S. The [[-2;;1;;-1]] approach is very nice.

Thank you all.

-
seems fine to me. I use Part quite a lot. I guess you could just insert the correct column numbers in the third line and skip the second line? To make this question better, post some example data. – Ajasja Jan 7 '14 at 20:14
@Ajasja this calls for the [[-2;;1;;-1]] thing from code golf :D – Yves Klett Jan 7 '14 at 20:26
@rm-rf the award for the Part part goes to you... – Yves Klett Jan 7 '14 at 21:55
As an aside, you probably might want to look at having a comma based delimiting for your data format (if you have control over it) instead of spaces, so that names with multi-word last names like de Vries, Sjoerd, C are handled properly instead of being transposed as Vries de (if you use space to delimit everything). – R. M. Jan 8 '14 at 16:29
@rm-rf You're right. Unfortunately, I am stuck with what my university's not so modern database is willing to output. The issue with multi-word names plague us like ***. FWIW I'm an instructor trying to get my class roster into a manageable form. – tbtom Jan 9 '14 at 17:15

Two ways I think will work for you, if not please provide some sample data:

list = ImportString["Lastname, Firstname, Initial
Lastname, Firstname, Initial
Lastname, Firstname, Initial
Lastname, Firstname, Initial
Lastname, Firstname, Initial
Lastname, Firstname, Initial", "CSV"];
list /. {l_, f_, i_} :> StringJoin[StringTrim[f], " ", StringTrim[l]]
(* Out: {"Firstname Lastname", "Firstname Lastname", "Firstname Lastname", \
"Firstname Lastname", "Firstname Lastname", "Firstname Lastname"} *}


Another that is also a bit shorter than what you have:

StringTrim[First@#] <> " " <> StringTrim[Last@#] & /@ list[[All, {2, 1}]]


Update. The example data that was added to the question is not actually a comma separated list but a table. There are also empty rows in the table which we have to deal with. Instead of the ImportString statement above, use the following:

list = ImportString["
lastname1 firstname2 Ii
lastname2 first2 Ii
lastna3 longfirstname2 Ii
", "Table"] /. {} -> Sequence[]

-
list = ImportString["
lastname1 firstname1 I1
lastname2 first2 I2
lastna3 longfirstname2 I3
", "Table"] /. {} -> Sequence[];

{#2, #} & @@@ list
(* {{"firstname1", "lastname1"}, {"first2", "lastname2"}, {"longfirstname2", "lastna3"}} *)

StringJoin[#2, " ", #] & @@@ list
(* {"firstname1 lastname1", "first2 lastname2", "longfirstname2 lastna3"} *)

-

For a single one of your strings:

string = "Lastname, Firstname, Initial";

StringTrim /@ StringSplit[string, ","][[-2 ;; 1 ;; -1]]


({"Firstname", "Lastname"})

-