Specify variable type for range of associative arrays.

Chris Davies via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 9 07:23:32 PDT 2015


On Sunday, 9 August 2015 at 12:54:39 UTC, Nicholas Wilson wrote:
> On Sunday, 9 August 2015 at 01:29:16 UTC, Christopher Davies 
> wrote:
>> [...]
> using UFCS (universal function call syntax) you would normally 
> write that as:
> records =records.filter!(r => r[where] == val)();
> and then leveraging D's optional parentheses as:
> records =records.filter!(r => r[where] == val)
> This allows you to chain them along with map, filter, reduce 
> etc. with ease
> e.g.
>     auto result = someRange.filter!(e 
> =>e.isFooCompatible).map!(e => foo(e)).map!(e => e.toBar).array;
>
> do you care about the type of result? Not really. It's a range. 
> meaning you can pass iterate over it, pass it to other 
> algorithms.
>
>>[...]
> Type inference is your friend.
>       auto foo = bar;
> will work for any type that does not disallow copying (@disable 
> this(this); )
>
> To answer your question what you probably want is not
>       auto records = csvReader!(string[string])(input, null);
>
>       if (where != "")
>       {
>              records = records.filter!(r => r[where] == val);
>       }
> but:
>       auto records = csvReader!(string[string])(input, null);
>
>       if (where != "")
>       {
>              auto filteredRecords = records.filter!(r => 
> r[where] == val);
>              //do something with filteredRecords ...
>       }
> or just
>       if (where != "")
>       {
>               // if you need the result exclude comment below
>               // or if your operation is for side effects only
>               // leave it.
>              /*auto result =*/ 
> csvReader!(string[string])(input, null)
>                                          .filter(e => 
> somePred(e))
>                                          
> .continueChainingRanges(withSomeArgs)
>                                          .untilYoureDone;
>
>       }
>
> If you just want a copy of the filtered results
>
> if (where != "")
>       {
>
>              auto result = csvReader!(string[string])(input, 
> null)
>                                          .filter(e => e[where] 
> == val).array;
>              // .array causes a separate copy of the values of 
> the result of csvReader
>
>       }
>
> Nic


Thanks so much for the reply. Good to know about UFCS.

The problem is, based on user input, I am optionally filtering a 
list, possibly passing it through 0, 1, 2 or more filters based 
on their input. Each successive filter runs on either the 
original range or the result of the previous filter, if there was 
one. Then I want to run a ussr-specified computation on the final 
range... So it would be very nice to be able to reassign the 
variable after each filter. Is there no good way to do that other 
than with Generator?


More information about the Digitalmars-d-learn mailing list