How do I use CTFE to generate an immutable associative array at compile time?

Chad Joan via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Feb 21 16:38:47 PST 2017


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.



More information about the Digitalmars-d-learn mailing list