how to get top N distinct elements from range?

Andrea Fontana nospam at example.com
Sat Mar 9 01:35:55 PST 2013


On Saturday, 9 March 2013 at 09:32:43 UTC, Andrea Fontana wrote:
> On Saturday, 9 March 2013 at 09:13:26 UTC, Andrea Fontana wrote:
>> On Saturday, 9 March 2013 at 01:36:53 UTC, bearophile wrote:
>>>
>>> Is it a good idea to replace std.algorithm.filter with 
>>> something like that filter2 (plus some missing methods)?
>>>
>>> Bye,
>>> bearophile
>>
>> Maybe two versions (filter and cachedFilter) or a bool 
>> template param?
>>
>> I was thinking about @pure front() too: but I think it's a 
>> wrong assumption. The right assumption would be that front 
>> should return the same value until popFront is called again. 
>> It can read front value lazily from front() call. It can do a 
>> lot of impure things (lol) but it shouldn't change front 
>> "randomly" at each call.
>>
>> I would improve distinct to support an alias pred = "a < b" to 
>> build a bst instead of an AA.
>>
>> Or just a field like distinct!"a.id" (that should work with aa 
>> backend)
>
> I almost got it:
>
> auto distinct(alias fun = "a", Range)(Range r)
> if (isInputRange!Range) {
> 	alias unaryFun!fun _fun;
>
> 	bool[ReturnType!_fun] mySet;
> 	
> 	return r.filter2!((k) {
> 					  	if (_fun(k) in mySet)
> 					  		return false;
> 					  	mySet[_fun(k)] = true;
> 					  	return true;
> 					  });
> }
>
> ReturnType!_fun doesn't work, if i set to the right type, 
> function works as expected


auto distinct(alias fun = "a", Range)(Range r)
if (isInputRange!Range) {
	alias unaryFun!fun _fun;

	bool[typeof(_fun((ElementType!Range).init))] mySet;
	
	return r.filter2!((k) {
					  	if (_fun(k) in mySet)
					  		return false;
					  	mySet[_fun(k)] = true;
					  	return true;
					  });
}


struct User
{
	int id;
	string name;
}

void main() {
	User[] users = [ {1, "first"}, {2, "second"}, {3, "first"}];

	users.distinct!("a.id")().writeln;
	users.distinct!("a.name")().writeln;

}

this works. Is this:
bool[typeof(_fun((ElementType!Range).init))] mySet;
	
the right way?


More information about the Digitalmars-d-learn mailing list