我有一个对象列表,它有两个属性,比方说 a
和 b
。 a
是一个枚举,例如:
[Flags] enum MyEnum
{
first = 1,
second = 2,
third = 4,
fourth = 8
};
b
是一个无符号整数,它是一个掩码(MyEnum 标志的组合)。
现在我需要通过它们的a
对每个对象求和 - 这意味着如果 obj.a = first | 一个对象可以求和两次第三个
,我似乎无法对它们执行groupBy
。是否有不同的求和方式?
很抱歉我没有分享我的代码,但我不能。我可以告诉你我只是在一些 if - else block 中使用 foreach 做到了这一点,但我认为我应该学习如何在 Linq 中做到这一点
编辑: 我想我不清楚。我想通过枚举对对象求和,这意味着如果我有:
obj1.a = first, obj1.b = 5
obj2.a = first | second, obj2.b = 3
那么输出就是
first sum = 8
second sum = 3
最佳答案
给定一个 MyEnum
和一个 MyClass
[Flags]
enum MyEnum
{
first = 1,
second = 2,
third = 4,
forth = 8
}
class MyClass
{
public MyEnum MyEnum;
public uint Value;
}
还有一些值(value)观
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 },
};
此 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) };
请注意,即使对于 MyEnum.fourth
,它也会返回一个“行”具有值(value) 0
.
表达式以枚举值 (Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
) 开始,然后对每个值求和 mcs
的值具有相同的 MyEnum
( mcs.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) };
表达式以枚举值 (Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
) 开始,然后对于每个值,它“保存”mcs
的值具有相同的 MyEnum
( let temp = mcs.Where(q => q.MyEnum.HasFlag(p)).Select(q => q.Value).ToArray()
) 在 temp
, 跳过 temp
为空 ( where temp.Length > 0
) 并对剩余的 temp
求和(select new { MyEnum = p, Sum = temp.Sum(q => q) }
)。请注意,如果您使用 uint
你必须使用 temp.Sum(q => q)
, 但带有 int
你可以使用 temp.Sum()
(或者您可以使用 temp.Sum(q => q)
)。
另一种方法是通过双 from
和一个 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) };
这可能等同于使用 SelectMany
正如 ChaseMedallion 所建议的那样(双 from
被编译器转换为 SelectMany
)
关于c# - LINQ - groupBy 与几个组中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18013604/