Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 24, 2015 Problem with map, reduce, .. | ||||
---|---|---|---|---|
| ||||
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. |
June 24, 2015 Re: Problem with map, reduce, .. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan | 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 ) );
|
June 24, 2015 Re: Problem with map, reduce, .. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adrian Matoga | On Wednesday, 24 June 2015 at 08:30:29 UTC, Adrian Matoga wrote:
> input.byLine() yields char[]'s as range elements, while props is (correctly) indexed by strings, i.e. immutable(char)[].
Ooops, more precisely it's because of the second argument of add() being string, but the solution above still applies.
|
June 24, 2015 Re: Problem with map, reduce, .. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adrian Matoga | On Wednesday, 24 June 2015 at 08:33:29 UTC, Adrian Matoga wrote:
> On Wednesday, 24 June 2015 at 08:30:29 UTC, Adrian Matoga wrote:
>> input.byLine() yields char[]'s as range elements, while props is (correctly) indexed by strings, i.e. immutable(char)[].
>
> Ooops, more precisely it's because of the second argument of add() being string, but the solution above still applies.
Thanks! That does it!
Any idea how to make the 'ugly' reduce step more 'pleasant'? I.e. make it a part of the filter, map, .. chain?
|
June 24, 2015 Re: Problem with map, reduce, .. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan | On Wednesday, 24 June 2015 at 08:58:10 UTC, Stefan wrote:
> On Wednesday, 24 June 2015 at 08:33:29 UTC, Adrian Matoga wrote:
>> On Wednesday, 24 June 2015 at 08:30:29 UTC, Adrian Matoga wrote:
>>> input.byLine() yields char[]'s as range elements, while props is (correctly) indexed by strings, i.e. immutable(char)[].
>>
>> Ooops, more precisely it's because of the second argument of add() being string, but the solution above still applies.
>
> Thanks! That does it!
>
> Any idea how to make the 'ugly' reduce step more 'pleasant'? I.e. make it a part of the filter, map, .. chain?
What about:
auto result = File(test.ini", "r")
.byLine()
.filter!( line => !startsWith( line, "#" ) && !startsWith( line, "!") && line.length > 0 )
.map!( line => line.idup.split('='))
.filter!( fields => fields.length > 1)
.map!( fields => tuple(fields[0].strip(), fields[1].strip() ))
.assocArray();
|
June 24, 2015 Re: Problem with map, reduce, .. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adrian Matoga | On Wednesday, 24 June 2015 at 09:35:35 UTC, Adrian Matoga wrote:
> On Wednesday, 24 June 2015 at 08:58:10 UTC, Stefan wrote:
>> On Wednesday, 24 June 2015 at 08:33:29 UTC, Adrian Matoga wrote:
>>> [...]
>>
>> Thanks! That does it!
>>
>> Any idea how to make the 'ugly' reduce step more 'pleasant'? I.e. make it a part of the filter, map, .. chain?
>
> What about:
>
> auto result = File(test.ini", "r")
> .byLine()
> .filter!( line => !startsWith( line, "#" ) && !startsWith( line, "!") && line.length > 0 )
> .map!( line => line.idup.split('='))
> .filter!( fields => fields.length > 1)
> .map!( fields => tuple(fields[0].strip(), fields[1].strip() ))
> .assocArray();
Wow! Very cool!
Thanks
|
Copyright © 1999-2021 by the D Language Foundation