On Tuesday, 21 February 2017 at 23:30:52 UTC, Chad Joan wrote:
On Tuesday, 21 February 2017 at 22:43:15 UTC, H. S. Teoh wrote:
Parsing strings at program startup is ugly and slow. What
about parsing at compile-time with CTFE into an array literal
and transforming that into an AA at startup, which should be a
lot faster?
// Warning: untested code
pure string[2][] parseTwoColumnCsv(string inputCsv)
{
import std.csv;
import std.typecons;
string[2][] result;
foreach (record;
csvReader!(Tuple!(string,string))(inputCsv)) {
result ~= [record[0], record[1]];
}
return result;
}
immutable string[string] dataLookup;
static this()
{
enum halfCookedData =
parseTwoColumnCsv(import("some_data.csv"));
foreach (p; halfCookedData) {
dataLookup[p[0]] = p[1];
}
}
T
Hi,
That makes a lot of sense and it had crossed my mind.
In my case the data sets are super small, so I'm probably going
to be lazy/productive and leave it the way it is.
Anyone else from the internet copying these examples: try to
just do it H.S. Teoh's way from the start ;)
Thanks for the suggestion.
- Chad
OK I couldn't help it:
---
pure private string[][] parseTwoColumnCsv(string inputCsv)
{
import std.csv;
import std.typecons;
string[][] result;
foreach ( record; csvReader!(Tuple!(string,string))(inputCsv) )
result ~= [record[0],record[1]];
return result;
}
pure private string[string] twoColumnArrayToAA(const string[][]
arr)
{
string[string] result;
foreach ( pair; arr )
result[pair[0]] = pair[1];
return result;
}
pure private string[string] importTwoColumnCsv(string csvFile)()
{
// Force the parse to happen at compile time.
immutable string[][] tempArray =
import(csvFile).parseTwoColumnCsv();
// Convert the parsed array into a runtime Associative Array and
return it.
return tempArray.twoColumnArrayToAA();
}
immutable string[string] dataLookup;
immutable string[string] dataLookup1;
immutable string[string] dataLookup2;
static this()
{
import std.range;
dataLookup1 = importTwoColumnCsv!"some_data1.csv";
dataLookup2 = importTwoColumnCsv!"some_data2.csv";
foreach( pair; chain(dataLookup1.byKeyValue,
dataLookup2.byKeyValue) )
dataLookup[pair.key] = pair.value;
}
void main()
{
import std.stdio;
writefln("dataLookup = %s", dataLookup);
}
---
This example also shows joining associative arrays.