Thread overview
Fetching an element using find
Jan 13, 2020
H. S. Teoh
Jan 13, 2020
H. S. Teoh
Jan 13, 2020
lithium iodate
January 13, 2020
I have a range (array), I want to find an element and get it from that array.

The code I'm writing looks like this:

auto answer = arr.find!((item,x) => item.id == x)(id);
enforce(!answer.empty, "id not in the range");
auto realAnswer = answer.front;

I can't do find(id).front, because that relies on asserts, which throw errors and kill the program, and are not always compiled in. I need an exception thrown so I can recover and report the error to the user.

But I hate to write 3 lines of code to do this every time.

I'm not seeing an easy solution in Phobos, am I missing it?

-Steve
January 13, 2020
On Mon, Jan 13, 2020 at 12:39:30PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:
> I have a range (array), I want to find an element and get it from that
> array.
> 
> The code I'm writing looks like this:
> 
> auto answer = arr.find!((item,x) => item.id == x)(id);
> enforce(!answer.empty, "id not in the range");
> auto realAnswer = answer.front;
> 
> I can't do find(id).front, because that relies on asserts, which throw errors and kill the program, and are not always compiled in. I need an exception thrown so I can recover and report the error to the user.
> 
> But I hate to write 3 lines of code to do this every time.
> 
> I'm not seeing an easy solution in Phobos, am I missing it?
[...]

Why not write your own convenience wrapper?

	auto firstElement(R)(R r)
		if (isInputRange!R)
	{
		if (r.empty) throw new Exception(...);
		return r.front;
	}

	auto e = myData.find!(e => blah(e)).firstElement;


T

-- 
I think Debian's doing something wrong, `apt-get install pesticide', doesn't seem to remove the bugs on my system! -- Mike Dresser
January 13, 2020
On 1/13/20 12:47 PM, H. S. Teoh wrote:
> 
> Why not write your own convenience wrapper?
> 
> 	auto firstElement(R)(R r)
> 		if (isInputRange!R)
> 	{
> 		if (r.empty) throw new Exception(...);
> 		return r.front;
> 	}
> 
> 	auto e = myData.find!(e => blah(e)).firstElement;

I certainly can (and did). I was wondering if there was something in Phobos to do it.

-Steve
January 13, 2020
On Mon, Jan 13, 2020 at 12:58:57PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:
> On 1/13/20 12:47 PM, H. S. Teoh wrote:
> > 
> > Why not write your own convenience wrapper?
> > 
> > 	auto firstElement(R)(R r)
> > 		if (isInputRange!R)
> > 	{
> > 		if (r.empty) throw new Exception(...);
> > 		return r.front;
> > 	}
> > 
> > 	auto e = myData.find!(e => blah(e)).firstElement;
> 
> I certainly can (and did). I was wondering if there was something in
> Phobos to do it.
[...]

Maybe add a new function to Phobos? :-D


T

-- 
It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe?
January 13, 2020
On Monday, 13 January 2020 at 17:58:57 UTC, Steven Schveighoffer wrote:
> On 1/13/20 12:47 PM, H. S. Teoh wrote:
>> 
>> Why not write your own convenience wrapper?
>> 
>> 	auto firstElement(R)(R r)
>> 		if (isInputRange!R)
>> 	{
>> 		if (r.empty) throw new Exception(...);
>> 		return r.front;
>> 	}
>> 
>> 	auto e = myData.find!(e => blah(e)).firstElement;
>
> I certainly can (and did). I was wondering if there was something in Phobos to do it.
>
> -Steve

`adjoin` can be used to run an inline lambda:
auto answer = arr.find!((item,x) => item.id == x)(id).adjoin!((n){enforce(!n.empty); return n.front;});

Using a simple alias you can have a flexible and nice to read solution:
alias ensure(alias pred) = (n, const(char)[] msg = "`ensure` failed"){enforce(pred(n), msg); return n;}; // module scope for UFCS!

auto answer = arr.find!((item,x) => item.id == x)(id).ensure!(n => !n.empty).front;
or with custom message:
auto answer = arr.find!((item,x) => item.id == x)(id).ensure!(n => !n.empty)("element with id not found").front;