www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What's equivalent to C#'s select?

reply Marc <jckj33 gmail.com> writes:
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
Jan 14
next sibling parent reply drug <drug2004 bk.ru> writes:
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);
Jan 14
parent reply Marc <jckj33 gmail.com> writes:
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
Jan 14
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
Jan 14
parent reply Marc <jckj33 gmail.com> writes:
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?
Jan 15
parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
Jan 15
prev sibling parent reply Seb <seb wilzba.ch> writes:
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
Jan 14
parent Marc <jckj33 gmail.com> writes:
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
Jan 14