Given a MyEnum and a MyClass
[Flags] enum MyEnum { first = 1, second = 2, third = 4, forth = 8 } class MyClass { public MyEnum MyEnum; public uint Value; }
And some values
var mcs = new[] { new MyClass { MyEnum = MyEnum.first | MyEnum.third, Value = 10 }, new MyClass { MyEnum = MyEnum.second, Value = 20 }, new MyClass { MyEnum = MyEnum.first, Value = 100 }, };
This LINQ expression will return for each value of the enum the sum of the values.
var ret = from p in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>() select new { MyEnum = p, Sum = mcs.Where(q => q.MyEnum.HasFlag(p)).Sum(q => q.Value) };
Note that it will return a "row" even for MyEnum.fourth with value 0.
The expression starts with the values of the enum (Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()) and then for each value it sums the values of the mcs that have the same MyEnum (mcs.Where(q => q.MyEnum.HasFlag(p)).Sum(q => q.Value))
If you want to exclude the values of the enum that aren't used:
var ret = from p in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>() let temp = mcs.Where(q => q.MyEnum.HasFlag(p)).Select(q => q.Value).ToArray() where temp.Length > 0 select new { MyEnum = p, Sum = temp.Sum(q => q) };
The expression starts with the values of the enum (Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()) and then for each value it "saves" the values of the mcs that have the same MyEnum (let temp = mcs.Where(q => q.MyEnum.HasFlag(p)).Select(q => q.Value).ToArray()) in temp, skips the temp that are empty (where temp.Length > 0) and sum the remaining temp (select new { MyEnum = p, Sum = temp.Sum(q => q) }). Note that if you use an uint you have to use temp.Sum(q => q), but with an int you can use temp.Sum() (or you can use temp.Sum(q => q)).
Another way is through a double from and a group by
var ret = from p in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>() from q in mcs where q.MyEnum.HasFlag(p) group q.Value by p into r select new { MyEnum = r.Key, Sum = r.Sum(p => p) };
It's probably equivalent to using the SelectMany as suggested by ChaseMedallion (a double from is converted by the compiler to a SelectMany)
obj3 = first | second | third;What are the sums? Can they befirst sum = 15,second sum = 8,third sum = 3,fourth sum = 7,fifth sum = 8,sixth sum = 14?