我有一个对象列表,有两个属性,让我们说a和b.a像Enum一样:
[Flags] enum MyEnum
{
first = 1,
second = 2,
third = 4,
fourth = 8
};
Run Code Online (Sandbox Code Playgroud)
b是无符号整数,它是一个掩码(MyEnum标志的组合).
现在我需要通过它们对每个对象求和a- 这意味着如果一个对象可以总结两次,obj.a = first | third而且我似乎无法groupBy对它们做一个.是否有不同的方式来总结它们?
对不起,我不分享我的代码,但我不能.我可以告诉你,我只是在一些if - else块中使用foreach,但我想我应该学习如何在Linq中做到这一点
编辑: 我想我不清楚.我想通过Enum总结对象,这意味着如果我有:
obj1.a = first, obj1.b = 5
obj2.a = first | second, obj2.b = 3
Run Code Online (Sandbox Code Playgroud)
然后输出将是
first sum = 8
second sum = 3
Run Code Online (Sandbox Code Playgroud)
给定 aMyEnum和 aMyClass
[Flags]
enum MyEnum
{
first = 1,
second = 2,
third = 4,
forth = 8
}
class MyClass
{
public MyEnum MyEnum;
public uint Value;
}
Run Code Online (Sandbox Code Playgroud)
和一些价值观
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 },
};
Run Code Online (Sandbox Code Playgroud)
此 LINQ 表达式将为枚举的每个值返回这些值的总和。
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) };
Run Code Online (Sandbox Code Playgroud)
MyEnum.fourth请注意,即使对于value ,它也会返回一个“行” 0。
该表达式以枚举 ( ) 的值开始,然后对于每个值,它对具有相同( )Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()的值求和mcsMyEnummcs.Where(q => q.MyEnum.HasFlag(p)).Sum(q => q.Value)
如果要排除未使用的枚举值:
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) };
Run Code Online (Sandbox Code Playgroud)
该表达式以枚举 ( ) 的值开始,然后对于每个值,它“保存”中具有相同( )Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()的值,跳过空值 ( ) 并对剩余的值求和( )。请注意,如果您使用 an 则必须使用,但使用 an则可以使用(或者可以使用)。mcsMyEnumlet temp = mcs.Where(q => q.MyEnum.HasFlag(p)).Select(q => q.Value).ToArray()temptempwhere temp.Length > 0tempselect new { MyEnum = p, Sum = temp.Sum(q => q) }uinttemp.Sum(q => q)inttemp.Sum()temp.Sum(q => q)
另一种方法是通过 doublefrom和 agroup 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) };
Run Code Online (Sandbox Code Playgroud)
它可能相当于使用SelectManyChaseMedallion 所建议的( doublefrom由编译器转换为 a SelectMany)