c# - LINQ - groupBy 与几个组中的项目

标签 c# linq

我有一个对象列表,它有两个属性,比方说 aba 是一个枚举,例如:

[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/

相关文章:

c# - 通过 COM 包装器从托管代码调用 COM 可见托管组件

c# - .NET 的 CryptoStream 的可寻找替代品?

C#简单开源应用

c# - 使用 Winforms 中运行的后台线程更新 UI 中的控件

c# - 将数组对转换为数组对(如果可能,使用 LINQ)

c# - 如何按日期时间值对字典进行排序

c# - customErrors 与自定义模块

c# - 如何按字母分组并放入相同的字母大小

c# - StructureMap InstanceScope.Hybrid 和 IDisposable

c# - 在枚举值上使用 Where