Using filter with std.container.Array.
Soulsbane via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Mar 22 19:53:40 PDT 2017
On Wednesday, 22 March 2017 at 07:30:48 UTC, Jonathan M Davis
wrote:
> On Wednesday, March 22, 2017 07:06:47 Soulsbane via
> Digitalmars-d-learn wrote:
>> Example code:
>> struct Foo
>> {
>> string name;
>> size_t id;
>> }
>>
>> Array!Foo foo_;
>>
>> I get errors when I try to use filter like this:
>>
>> auto found = filter!((Foo data, size_t id) => data.id ==
>> id)(foo_[], 100);
>>
>> I get this error
>> source/app.d(15,62): Error: template
>> std.algorithm.iteration.filter!(function (Foo data, ulong id)
>> =>
>> data.id == id).filter cannot deduce function from argument
>> types
>> !()(RangeT!(Array!(Foo)), int), candidates are:
>> /usr/include/dmd/phobos/std/algorithm/iteration.d(1089,10):
>> std.algorithm.iteration.filter!(function (Foo data, ulong
>> id) =>
>> data.id == id).filter(Range)(Range range) if
>> (isInputRange!(Unqual!Range))
>>
>> I can't figure out what I'm doing wrong. Thanks!
>
> filter takes a unary predicate that gets called on each element
> in a range. It's not going to work with a function that takes
> two arguments, and filter itself isn't going to take two
> arguments. You could do something like
>
> auto result = filter!(a => a.id == 100)(foo_[]);
>
> but you can't pass multiple arguments to filter. Also, if
> you're looking to find an element, then find would make more
> sense than filter, since filter is going to give you a lazy
> range with every element that matches the predicate, whereas
> find is just going to iterate the range until it finds the
> element (or is empty) and then returns the range. But I don't
> know whether calling the variable found was just the name you
> came up with or whether you're really trying to do a find
> operation rather than filter.
>
> - Jonathan M Davis
Thanks for the reply Jonathan! Yes, I was trying to find all the
ids that match but couldn't get find to work. So I think I have
missed something somewhere.
As a quick example:
import std.stdio;
import std.algorithm;
import std.container;
struct Foo
{
string name;
size_t id;
}
Array!Foo foo_;
void main(string[] arguments)
{
Foo first;
first.id = 200;
Foo second;
second.id = 100;
Foo third;
third.id = 345;
Foo fourth;
fourth.id = 100;
foo_.insert(first);
foo_.insert(second);
foo_.insert(third);
foo_.insert(fourth);
auto filterIt = filter!((Foo data) => data.id == 100)(foo_[]);
auto foundIt = find!((Foo data) => data.id == 100)(foo_[]);
writeln(filterIt);
writeln(foundIt);
}
Will print:
[Foo("", 100), Foo("", 100)]
[Foo("", 100), Foo("", 345), Foo("", 100)]
I only want the ids that match 100. Looking at find's
documentation it looks like it's returning exactly as it should
but not the way I want. No 345 id.
Thanks for the help. I have this code working just fine using
foreach and have been trying to learn this different way of doing
things lately and my brain hurts :). Thanks again.
More information about the Digitalmars-d-learn
mailing list