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