Reputation: 108937
I have two queries and i'm using the result of the first one in the second one like this
var temp = (ObjectTable.Where(o => o.Category == "Y"));
var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == temp.Max(x => x.Value))});
Is there a way to combine these into one query?
EDIT: I cannot just chain them directly because I'm using temp.Max() in the second query.
Upvotes: 1
Views: 472
Reputation: 28698
You can do it in one statement using query syntax, using the let
keyword. It only evaluates the 'max' once, so it just like the three separate statements, just in one line.
var anonymousObjList = from o in ObjectTable
where o.Category == "Y"
let max = ObjectTable.Max(m => m.Value)
select new { o, IsMax = (o.Value == max) };
This is the only time I ever use query syntax. You can't do this using method syntax!
edit: ReSharper suggests
var anonymousObjList = ObjectTable.Where(o => o.Category == "Y")
.Select(o => new {o, max = ObjectTable.Max(m => m.Value)})
.Select(@t => new {@t.o, IsMax = (@t.o.Value == @t.max)});
however this is not optimal. The first Select is projecting a max
Property for each item in ObjectTable - the Max function will be evaluated for every item. If you use query syntax it's only evaluated once.
Again, you can only do this with query syntax. I'm not fan of query syntax but this makes it worthwhile, and is the only case in which I use it. ReSharper is wrong.
Upvotes: 1
Reputation: 13104
Possibly the most straightfirward refactoring is to replace all instances of "temp" with the value of temp. Since it appears that this value is immutable, the refactoring should be valid (yet ugly):
var anonymousObjList = ObjectTable.Where(o => o.Category == "Y")
.Select(o => new {o, IsMax = (o.Value == ObjectTable.Where(o => o.Category == "Y").Max(x => x.Value))});
As has already been pointed out, this query really has no advantages over the original, since queries use deffered execution and can be built up. I would actually suggest splitting the query even more:
var temp = (ObjectTable.Where(o => o.Category == "Y"));
var maxValue = temp.Max(x => x.Value);
var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == maxValue)});
This is better than the original because every time "Max" is called causes another iteration over the entire dataset. Since it is being called in the Select of the original, Max was being called n times. That makes the original O(n^2)!
Upvotes: 1
Reputation: 564
Why? it would be clearer (and more efficient) to make it three:
var temp = (ObjectTable.Where(o => o.Category == "Y"));
int max = temp.Max(x => x.Value);
var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == max)});
Upvotes: 5