C
C#2y ago
Dyad

How to do this with LINQ?

``` var values = new []{ 1, 2, 3, 4, 5} int winner; for(int i = 0; i < values.Count; i++) { var value = values[i]; var r = value * 2; if(r > 7) { winner = r; break; } }
41 Replies
Moods
Moods2y ago
What does value end up doing
Jimmacle
Jimmacle2y ago
var winner = values.FirstOrDefault(x => x * 2 > 7)?
Dyad
DyadOP2y ago
I know I can do values.Select(v => v * 2).Where(r => r > 7).First() but I want to do it efficiently
mindhardt
mindhardt2y ago
More like LastOrDefault
Dyad
DyadOP2y ago
I don't want to do the computation if something wins early
Jimmacle
Jimmacle2y ago
why last? it breaks at the first winner
Moods
Moods2y ago
they’re comparing indices not values are they not?
mindhardt
mindhardt2y ago
Ah true
Jimmacle
Jimmacle2y ago
yeah i'm assuming there's a typo in this part
var value = values[i];
var r = i * 2;
var value = values[i];
var r = i * 2;
mindhardt
mindhardt2y ago
This one is pretty much efficient, linq chain is executed as many times as needed
Jimmacle
Jimmacle2y ago
yeah the only efficiency to be gained is typing less by putting the whole expression in FirstOrDefault (default because there may not be any winner)
Dyad
DyadOP2y ago
in my case I have a more complex algorithm I don't want to run if there is an early winner
Jimmacle
Jimmacle2y ago
and performance wise, a plain loop is probably faster than linq anyway
mindhardt
mindhardt2y ago
First(OrDefault) runs till it either finds a winner or collection ends Their difference is the behavior in case of no winners
Dyad
DyadOP2y ago
the problem with first or default is it doesn't remember the computation
Moods
Moods2y ago
Tempted to agree but LINQ’s probably been optimized to hell they could be virtually the same
mindhardt
mindhardt2y ago
Wym
Dyad
DyadOP2y ago
values.FirstOrDefault(v => v x 2 > 7) x 2
mindhardt
mindhardt2y ago
This, or
Dyad
DyadOP2y ago
I would have to do the math again on the winning value cause it doesn't remember the computation that happened in the lamba
mindhardt
mindhardt2y ago
values.Select(x => x * 2).FirstOrDefault(x => x > 7)
Jimmacle
Jimmacle2y ago
^ but then you don't know who the winner is
Dyad
DyadOP2y ago
I want to terminate early
mindhardt
mindhardt2y ago
Do they need to?
Dyad
DyadOP2y ago
so I can't just select on all values
Jimmacle
Jimmacle2y ago
select doesn't enumerate the whole list
mindhardt
mindhardt2y ago
I guess you don't understand linq chains
Jimmacle
Jimmacle2y ago
linq is evaluated lazily the computation is only done when the next value is needed, like when you're materializing the result with First
mindhardt
mindhardt2y ago
It doesn't equal to two loops: one for .Select and one for FirstOrDefault It equals to one loop which firstly transforms and then checks and may or may not return
Jimmacle
Jimmacle2y ago
how many values are you computing this on?
Moods
Moods2y ago
All Select does is create an object to hold the lambda and source array/list (very watered down explanation)
Jimmacle
Jimmacle2y ago
because unless it's millions it doesn't even matter a single multiplication is very cheap
Dyad
DyadOP2y ago
oh it runs both lambdas on the first value and will only proceed to the next if the 2nd lambda condition is not met?
Jimmacle
Jimmacle2y ago
essentially
mindhardt
mindhardt2y ago
More or less
Dyad
DyadOP2y ago
oh, you learn something new everyday thanks guys 🙂
mindhardt
mindhardt2y ago
$close
MODiX
MODiX2y ago
Use the /close command to mark a forum thread as answered
Moods
Moods2y ago
Yeah both lambdas get evaluated in the FirstOrDefault call
Jimmacle
Jimmacle2y ago
i will reiterate that if performance is the goal and you're concerned about a single multiplication taking too long, you shouldn't be using linq
mindhardt
mindhardt2y ago
But linq is so comfy catpog

Did you find this page helpful?