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.