Thread overview
What's equivalent to C#'s select?
Jan 14, 2018
Marc
Jan 14, 2018
drug
Jan 14, 2018
Marc
Jan 15, 2018
Simen Kjærås
Jan 15, 2018
Marc
Jan 15, 2018
Simen Kjærås
Jan 14, 2018
Seb
Jan 14, 2018
Marc
January 14, 2018
give a list, how can I select only the elements of a range according to a condition give by a lamba function?

something like this:

> auto l = myList.select(e => e.id < 300);

it would return a range. Similar to C#'s select:

https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
January 15, 2018
15.01.2018 00:21, Marc пишет:
> give a list, how can I select only the elements of a range according to a condition give by a lamba function?
> 
> something like this:
> 
>> auto l = myList.select(e => e.id < 300);
> 
> it would return a range. Similar to C#'s select:
> 
> https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
import std.algorithm : filter;

auto l = myList.filter!(e => e.id < 300);
January 14, 2018
On Sunday, 14 January 2018 at 21:21:52 UTC, Marc wrote:
> give a list, how can I select only the elements of a range according to a condition give by a lamba function?
>
> something like this:
>
>> auto l = myList.select(e => e.id < 300);
>
> it would return a range. Similar to C#'s select:
>
> https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx

Shameless self-plug - you might like this (incomplete) comparison between LINQ and D ranges:

https://github.com/wilzbach/linq
January 14, 2018
On Sunday, 14 January 2018 at 21:38:39 UTC, drug wrote:
> 15.01.2018 00:21, Marc пишет:
>> give a list, how can I select only the elements of a range according to a condition give by a lamba function?
>> 
>> something like this:
>> 
>>> auto l = myList.select(e => e.id < 300);
>> 
>> it would return a range. Similar to C#'s select:
>> 
>> https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
> import std.algorithm : filter;
>
> auto l = myList.filter!(e => e.id < 300);

thanks, can i use it at compile time as well?

>	enum isMutableString(string field) = is(typeof(__traits(getMember, >C, field)) == string);
>	static foreach(field; [FieldNameTuple!C].filter!(f => 
>>isMutableString!(f))) {
>		writeln(field);
>	}

give error:

> Error: variable f cannot be read at compile time
January 14, 2018
On Sunday, 14 January 2018 at 21:59:26 UTC, Seb wrote:
> On Sunday, 14 January 2018 at 21:21:52 UTC, Marc wrote:
>> give a list, how can I select only the elements of a range according to a condition give by a lamba function?
>>
>> something like this:
>>
>>> auto l = myList.select(e => e.id < 300);
>>
>> it would return a range. Similar to C#'s select:
>>
>> https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
>
> Shameless self-plug - you might like this (incomplete) comparison between LINQ and D ranges:
>
> https://github.com/wilzbach/linq

Sounds pretty interesting, I'll give a try! Thanks
January 15, 2018
On Sunday, 14 January 2018 at 22:07:22 UTC, Marc wrote:
> thanks, can i use it at compile time as well?
>
>>	enum isMutableString(string field) = is(typeof(__traits(getMember, >C, field)) == string);
>>	static foreach(field; [FieldNameTuple!C].filter!(f =>
>>>isMutableString!(f))) {
>>		writeln(field);
>>	}

You're mixing compile-time and run-time logic here in a way that D doesn't allow. In particular, isMutableString requires the passed string to be a compile-time constant, and filter works on run-time values.

There are a few different ways to resolve this. First, std.meta has the Filter template, which behaves much in the same way as std.algorithm.filter, but with compile-time tuples:

static foreach (field; Filter!(isMutableString, FieldNameTuple!C)) {
    writeln(field);
}

The other option is to rewrite isMutableString to work with run-time values:

bool isMutableString(string field) {
    switch (field) {
        foreach (cField; FieldNameTuple!C) {
            case cField:
                return is(typeof(__traits(getMember, C, cField)) == string);
        }
        default:
            return false;
    }
}
static foreach(field; [FieldNameTuple!C].filter!(f => isMutableString(f))) {
    writeln(field);
}

Both of these give the same output, and should be what you want.

--
  Simen
January 15, 2018
On Monday, 15 January 2018 at 07:37:42 UTC, Simen Kjærås wrote:
> On Sunday, 14 January 2018 at 22:07:22 UTC, Marc wrote:
>> thanks, can i use it at compile time as well?
>>
>>>	enum isMutableString(string field) = is(typeof(__traits(getMember, >C, field)) == string);
>>>	static foreach(field; [FieldNameTuple!C].filter!(f =>
>>>>isMutableString!(f))) {
>>>		writeln(field);
>>>	}
>
> You're mixing compile-time and run-time logic here in a way that D doesn't allow. In particular, isMutableString requires the passed string to be a compile-time constant, and filter works on run-time values.

I just thought that filter() could be evaluated at compile time too, as others function that I've used so far. Sometimes I don't know if a native function can be evaluated at compile time until I do enum x = func();

> There are a few different ways to resolve this. First, std.meta has the Filter template, which behaves much in the same way as std.algorithm.filter, but with compile-time tuples:
>
> static foreach (field; Filter!(isMutableString, FieldNameTuple!C)) {
>     writeln(field);
> }
>
> The other option is to rewrite isMutableString to work with run-time values:
>
> bool isMutableString(string field) {
>     switch (field) {
>         foreach (cField; FieldNameTuple!C) {
>             case cField:
>                 return is(typeof(__traits(getMember, C, cField)) == string);
>         }
>         default:
>             return false;
>     }
> }
> static foreach(field; [FieldNameTuple!C].filter!(f => isMutableString(f))) {
>     writeln(field);
> }
>
> Both of these give the same output, and should be what you want.
>
> --
>   Simen

That's exactly it! That Filter() from std.algorithm works like I wanted :) nice solution also with rewrite the function to work with run-time so that i can use with filter() but if I want to have minimum runtime code to filter out immutable strings, the first one is better right?
January 15, 2018
On Monday, 15 January 2018 at 15:24:50 UTC, Marc wrote:
> I just thought that filter() could be evaluated at compile time too, as others function that I've used so far. Sometimes I don't know if a native function can be evaluated at compile time until I do enum x = func();

Yeah, it takes some getting used to what happens when and how these interact. I can recommend H. S. Teoh's writeup: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time

> if I want to have minimum runtime code to filter out immutable strings, the first one is better right?

Indeed. It generates the equivalent code to just writing the writeln()s you want, with no run-time overhead.

--
  Simen