1
$\begingroup$

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.

$\endgroup$
5
  • 1
    $\begingroup$ 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. $\endgroup$
    – Ajasja
    Commented Jan 7, 2014 at 20:14
  • 1
    $\begingroup$ @Ajasja this calls for the [[-2;;1;;-1]] thing from code golf :D $\endgroup$
    – Yves Klett
    Commented Jan 7, 2014 at 20:26
  • $\begingroup$ @rm-rf the award for the Part part goes to you... $\endgroup$
    – Yves Klett
    Commented Jan 7, 2014 at 21:55
  • $\begingroup$ 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). $\endgroup$
    – rm -rf
    Commented Jan 8, 2014 at 16:29
  • $\begingroup$ @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. $\endgroup$
    – tbtom
    Commented Jan 9, 2014 at 17:15

4 Answers 4

2
$\begingroup$

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[]
$\endgroup$
0
2
$\begingroup$
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"} *)
$\endgroup$
1
$\begingroup$
list = 
 {{"Allen", "Mike", "G."}, {"Roe", "Mary", "E."}, {"Carter", "Susan", "I."}};

Using StringRiffle (new in 10.1)

StringRiffle @* Reverse @* Most /@ list

{"Mike Allen", "Mary Roe", "Susan Carter"}

$\endgroup$
0
$\begingroup$

For a single one of your strings:

string = "Lastname, Firstname, Initial";

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

({"Firstname", "Lastname"})

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.