Problem with map, reduce, ..

Adrian Matoga via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jun 24 01:30:28 PDT 2015


On Wednesday, 24 June 2015 at 08:18:52 UTC, Stefan wrote:
> I tried to refactor some existing code to use more of the 
> functional patterns/style (map, filter, reduce, ..).
> The task is to read in some sort of a simple property file and 
> present the result as an associative array.
> My attempt is:
>
> import std.stdio;
> import std.algorithm.iteration : filter, map, reduce;
> import std.algorithm.mutation : split;
> import std.string : indexOf, strip;
> import std.stdio : File, writeln;
> import std.algorithm : startsWith;
>
> string[string] add( ref string[string] result, in string line) {
>     int assignmentIndex = indexOf( line, "=" );
>     if ( assignmentIndex > 0 ) {
>         string key = line[ 0 .. assignmentIndex ];
>         string value = line[ assignmentIndex + 1 .. line.length 
> ];
>         result[ key ] = value;
>    }
>    return result;
> }
>
>
> void main() {
>    auto input = File( "test.ini", "r" );
>    auto lines = input.byLine()
>       .filter!( line => !startsWith( line, "#" ) && 
> !startsWith( line, "!") && line.length > 0 )
>       .map!( line => strip( line ) );
>    string[string] props;
>    auto result = reduce!(add)( props, lines );
> }
>
> result should now contain the associative array.
>
> However, it fails with an error in the "reduce" line:
>
> c:\develop\dmd2.067.1\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(2536): Error: static assert  "Incompatible function/seed/element: prop.add/string[string]/char[]"
> c:\develop\dmd2.067.1\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(2521):        instantiated from here: reduceImpl!(false, MapResult!(__lambda2, FilterResult!(__lambda1, ByLine!(char, char))), string[string])
> c:\develop\dmd2.067.1\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(2505):        instantiated from here: reducePreImpl!(MapResult!(__lambda2, FilterResult!(__lambda1, ByLine!(char, char))), string[string])
> source\prop.d(30):        instantiated from here: 
> reduce!(string[string], MapResult!(__lambda2, 
> FilterResult!(__lambda1, ByLine!(char, char))))
>
> I have no idea how to resolve this.

input.byLine() yields char[]'s as range elements, while props is 
(correctly) indexed by strings, i.e. immutable(char)[]. Use .idup 
to create an immutable copy of the property name, e.g.:

    auto lines = input.byLine()
       .filter!( line => !startsWith( line, "#" ) && !startsWith( 
line, "!") && line.length > 0 )
       .map!( line => strip( line.idup ) );



More information about the Digitalmars-d-learn mailing list