假设我有
[Flags]
public enum MyEnum
{
ValueZero = 1,
ValueOne = 2,
ValueTwo = 4
}
public class MyClass
{
public string Property { get; set; }
public MyEnum EnumValue { get; set; }
}
我希望能够在GroupBy
上使用List<MyClass>
按枚举进行分组,而不考虑它是一个标记枚举。
当我使用GroupBy
时(问题末尾的示例),分组是使用这样的聚合枚举制作的
//Grouping Values
ValueZero | ValueOne : myClass1, myClass2
ValueOne | ValueTwo : myClass3, myClass4
我希望得到以下内容(使用GroupBy方法,因为它比使用Where
3次更高效)
//Grouping Values
ValueZero : myClass1, myClass2
ValueOne : myClass1, myClass2, myClass3, myClass4
ValueTwo : myClass4
我认为使用它会起作用:
var list = new List<MyClass>();
var groupedList = list.GroupBy(c => c.EnumValue);
答案 0 :(得分:1)
如果我猜你的意图而不是在代码中它有这样的实现:
var list = new List<MyClass>();
list.Add(new MyClass() {
EnumValue = MyEnum.ValueZero | MyEnum.ValueOne, Property = "myClass1"
});
list.Add(new MyClass() {
EnumValue = MyEnum.ValueZero | MyEnum.ValueOne, Property = "myClass2"
});
list.Add(new MyClass() {
EnumValue = MyEnum.ValueOne , Property = "myClass3"
});
list.Add(new MyClass() {
EnumValue = MyEnum.ValueOne | MyEnum.ValueTwo, Property = "myClass4"
});
var enumValues = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToArray();
var grouped = list.SelectMany(
o => enumValues
.Where(flag => o.EnumValue.HasFlag(flag))
.Select(v => new { o, v })
)
.GroupBy(t => t.v, t => t.o);
foreach (IGrouping<MyEnum, MyClass> group in grouped)
{
Console.WriteLine(group.Key.ToString() + ": " + string.Join(", ", group.Select(x=>x.Property)));
}
答案 1 :(得分:0)
首先将每个枚举值拆分为单独的标志(如shown here),然后展平结果和组。
它应该是这样的:
var groupedList = list
.Select(c => new { Flags=GetFlags(c.EnumValue), Item=c }) // split flags
.SelectMany(c => c.Flags.Select(x => new { Flag=x, Item=c.Item })) // flatten
.GroupBy(c => c.Flag, i => i.Item); // group
其中GetFlags
是获取单个枚举标记的方法,如链接答案中的方法:
static IEnumerable<MyEnum> GetFlags(MyEnum input)
{
return Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
.Where(f => input.HasFlag(f));
}