reduce number of LINQ queries
void Main()
{
List<SomeContainer> someList = new List<SomeContainer>();
someList.Add(new SomeContainer { a = true, b = true, c = true });
someList.Add(new SomeContainer { a = false, b = true, c = false });
someList.Add(new SomeContainer { a 开发者_运维技巧= true, b = true, c = false });
someList.Add(new SomeContainer { a = true, b = false, c = false });
someList.Add(new SomeContainer { a = true, b = false, c = false });
someList.Add(new SomeContainer { a = true, b = true, c = false });
someList.Add(new SomeContainer { a = true, b = true, c = false });
var q1 = from container in someList where container.a == true select container.a;
var q2 = from container in someList where container.b == true select container.b;
var q3 = from container in someList where container.c == true select container.c;
q1.Count().Dump();
q2.Count().Dump();
q3.Count().Dump();
}
class SomeContainer
{
public Boolean a { get; set; }
public Boolean b { get; set; }
public Boolean c { get; set; }
}
is it possible to generate something like this with one querry:
a | b | c6 | 5 | 1Not sure whether you will treat this as optimization, but this will iterate over your list only once:
var result = someList
.Select(i => new [] {i.a? 1:0, i.b? 1:0, i.c? 1:0,})
.Aggregate((i, acc) => new [] {i[0]+acc[0], i[1]+acc[1], i[2]+acc[2]});
int countA = result[0];
int countB = result[1];
int countC = result[2];
int a = 0, b = 0, c = 0;
var qAll = (from ct in someList
select new{ ac = ct.a ? a++ : 0,
bc = ct.b ? b++ : 0,
cc = ct.c ? c++ : 0}).ToList();
//Now a, b, c variables should have the count of a==true, b==true & c==true in somelist.
//Console.WriteLine("A= {0}, B={1}, C={2}", a, b, c);
The Aggregate
extension methods allow you combine values from enumerables in arbitrary ways. You can aggregate a tuple of three integers representing a count, and provide a function that will increment the three counters on the tuple depending on the input.
It suspect it may could look contrived for this example, and it may be slower than a regular for loop.
Sometimes Aggregate
shines though. I used it to compute the bounding rectangle of a list of rectangles: var union = rects.Aggregate(Rectangle.Union);
someList.Count(container => container.a).Dump();
someList.Count(container => container.b).Dump();
someList.Count(container => container.c).Dump();
//even when looking for false values it looks nice...
someList.Where(container => container.a == false).Count(container => container.a).Dump();
精彩评论