www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Filter and sort associative array

reply Head Scratcher <filter stumped.com> writes:
I am just learning D. So far, I am impressed by its elegance and 
power.

I have an associative array bool[string]. I want to filter it by 
value (!bool), then extract the keys and sort them. I am 
struggling with the syntax and working with ranges. I can't find 
any documentation related to filtering associative arrays.

This is what I currently have, but it doesn't compile:

auto sortedStrings = myAssocArray.byKeyValue.filter!((string 
k,value) => !value).assocArray.keys.sort();
Jan 11
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Jan 11, 2019 at 03:20:20PM +0000, Head Scratcher via
Digitalmars-d-learn wrote:
 I am just learning D. So far, I am impressed by its elegance and power.
 
 I have an associative array bool[string]. I want to filter it by value
 (!bool), then extract the keys and sort them. I am struggling with the
 syntax and working with ranges. I can't find any documentation related to
 filtering associative arrays.
 
 This is what I currently have, but it doesn't compile:
 
 auto sortedStrings = myAssocArray.byKeyValue.filter!((string k,value) =>
 !value).assocArray.keys.sort();
I recommend using std.array.byPair rather than .byKeyValue, like this: auto sortedStrings = myAssocArray.byPair .filter!(pair => !pair[1]) // pair[1] is the value .map!(pair => pair[0]) // pair[0] is the key .array .sort; The .array call is needed because .byPair returns a non-random access range, which cannot be sorted. So you need to create an array first then sort that. Also, there's no need to reconstruct another AA with the filtered entries -- it allocates a new AA which is wasteful. All you really need is the filter the keys, then sort the keys. T -- If the comments and the code disagree, it's likely that *both* are wrong. -- Christopher
Jan 11
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/11/19 10:20 AM, Head Scratcher wrote:
 I am just learning D. So far, I am impressed by its elegance and power.
 
 I have an associative array bool[string]. I want to filter it by value 
 (!bool), then extract the keys and sort them. I am struggling with the 
 syntax and working with ranges. I can't find any documentation related 
 to filtering associative arrays.
 
 This is what I currently have, but it doesn't compile:
 
 auto sortedStrings = myAssocArray.byKeyValue.filter!((string k,value) => 
 !value).assocArray.keys.sort();
 
import std.range; import std.algorithm; import std.array; auto sortedStrings = myAssocArray .byKeyValue .filter!(kvp => !kvp.value) // kvp = key value pair .map!(kvp => kvp.key) // map to the key strings .array // form a sortable array .sort; // sort it Note the nice formatting to show how the range pipeline goes, and allows for comments explaining each step. -Steve
Jan 11
parent reply Head Scratcher <filter stumped.com> writes:
Thank you. This works great. What I don't understand is how a 
key-value pair ends up being a set of strings. Where did the 
value of the key-value pair get removed?  According to the 
library documentation, the array function "allocates an array and 
initializes it with copies of the elements of range r." So 
wouldn't the resulting array contain pairs? And if so, how does 
the sort work on pairs?
Jan 11
parent reply Alex <sascha.orlov gmail.com> writes:
On Friday, 11 January 2019 at 16:02:27 UTC, Head Scratcher wrote:
 Thank you. This works great. What I don't understand is how a 
 key-value pair ends up being a set of strings. Where did the 
 value of the key-value pair get removed?  According to the 
 library documentation, the array function "allocates an array 
 and initializes it with copies of the elements of range r." So 
 wouldn't the resulting array contain pairs? And if so, how does 
 the sort work on pairs?
By map you map the pair to its key resp. its first element. The result of the map contains the right-hand side of the "=>" expression only.
Jan 11
parent Head Scratcher <filter stumped.com> writes:
On Friday, 11 January 2019 at 16:06:48 UTC, Alex wrote:
 On Friday, 11 January 2019 at 16:02:27 UTC, Head Scratcher 
 wrote:
 Thank you. This works great. What I don't understand is how a 
 key-value pair ends up being a set of strings. Where did the 
 value of the key-value pair get removed?  According to the 
 library documentation, the array function "allocates an array 
 and initializes it with copies of the elements of range r." So 
 wouldn't the resulting array contain pairs? And if so, how 
 does the sort work on pairs?
By map you map the pair to its key resp. its first element. The result of the map contains the right-hand side of the "=>" expression only.
Ah, that makes sense. Thank you for the explanation.
Jan 11