# Mapping StringToDouble over nested lists of strings, still confused about slots

This is a simple question about slots but I still cant see how to do it after searching stackexchange.

(I'm importing a large data file as text and to convert to numbers I think it'll be quicker to import it all as a list of strings and then apply InternalStringToDouble to each element rather than using Import "Table". I can relatively quickly importing using Import["file","CSV"] as opposed to Import["file","Table"] which would convert it to data for me but slowly).

So say I have a list of strings test:

test={{"1.e9    2.e9    3.e9    4.e9    5.e9"}, {"1.e10 2.e10   3.e10   4.e10   5.e10"}, {"1.e11    2.e11   3.e11   4.e11   5.e11"}, {"1.e12    2.e12   3.e12   4.e12   5.e12"}}


Then I want to split this into lists of data. For a single line this works:

line=1;
InternalStringToDouble[StringSplit[test[[line, 1]]][[#]]] & /@ Range@5


But what is the syntax for including a #2 to apply this over all lines?

InternalStringToDouble[StringSplit[test[[#2, 1]]][[#]]] & /@ Range@5

• Try Map[InternalStringToDouble, StringSplit @@@ test, {2}] and report back. Feb 25, 2016 at 18:12
• Yes! That works. And I tried it on my large file and got timing ~13s compared to 22s using Import with "Table". Great! Now I need to see how to include Alex Nazarovsky's very fast writing routine "Mex_writeMatrix" in Mathematica, (it is written in c, and I use it in matlab instead of the standard formatted output routine. See nazarovsky.ru/2014/08/22/…). Please can you make your comment an answer so I can vote it up? Feb 25, 2016 at 18:26
• @J.M. Out of curiosity, is there a way to do this using # and #2 or am I missing the point of slots? Feb 25, 2016 at 21:53
• It can be done with slots, sure. As you've seen, they are not really needed, tho. Feb 26, 2016 at 1:20

## 1 Answer

To settle this:

You need to use level-1 Apply[] with StringSplit[] to replace the list containing a single string with the list produced by StringSplit[]:

StringSplit @@@ test
{{"1.e9", "2.e9", "3.e9", "4.e9", "5.e9"},
{"1.e10", "2.e10", "3.e10", "4.e10", "5.e10"},
{"1.e11", "2.e11", "3.e11", "4.e11", "5.e11"},
{"1.e12", "2.e12", "3.e12", "4.e12", "5.e12"}}


(More explicitly: Apply[StringSplit, test, {1}].)

You can now use Map[f, matrix, {2}] to map f over the entries of a given matrix. Combining this with the previous line, the final snippet is thus

Map[InternalStringToDouble, StringSplit @@@ test, {2}]
{{1.*^9, 2.*^9, 3.*^9, 4.*^9, 5.*^9},
{1.*^10, 2.*^10, 3.*^10, 4.*^10, 5.*^10},
{1.*^11, 2.*^11, 3.*^11, 4.*^11, 5.*^11},
{1.*^12, 2.*^12, 3.*^12, 4.*^12, 5.*^12}}
`