使用Linq进行分组的按位运算

时间:2012-02-21 11:37:55

标签: linq bit-manipulation

我有像

这样的数据
public class PermList
{
    public int UserId { get; set; }
    public int GroupId { get; set; }
    public int ModuleId { get; set; }
    public int BitMaskedPermission { get; set; }

    public List<PermList> TestData()
    {
        List<PermList> theList = new List<PermList>();
        PermList sample1 = new PermList {BitMaskedPermission = 15, GroupId = 3, ModuleId = 2, UserId = 1};
        theList.Add(sample1);
        PermList sample2 = new PermList { BitMaskedPermission = 2, GroupId = 3, ModuleId = 1, UserId = 1 };
        theList.Add(sample2);
        PermList sample3 = new PermList { BitMaskedPermission = 48, GroupId = 2, ModuleId = 2, UserId = 1 };
        theList.Add(sample3);
        return theList;
    }
}

enter image description here

我想通过分组ModuleId将OR应用于BitMaskedPermissions。这是我想要的;

enter image description here

如何使用Linq实现此目的。

TIA。

2 个答案:

答案 0 :(得分:4)

当您要执行的聚合操作不是内置的(SumMax等)时,您必须转向Aggregate,这是更冗长但也更强大。在这里,你想要

var data = TestData();
var grouped = 
    from permList in data
    group permList by new { permList.UserId, permList.ModuleId } into g
    select new { // or a named class if you have one
        g.Key.UserId,
        g.Key.ModuleId,
        BitMaskedPermission 
            = g.Aggregate(0, (acc, curr) => acc | curr.BitMaskedPermission)
    };

在这里,我们传递Aggregate一个函数,该函数接受累加器 acc当前值 curr,以及按位OR他们来获得持续的累积值。

如果您更喜欢方法链式语法,它看起来像(@Chris提供):

var grouped = PermList.TestData()
    .GroupBy(x=> new{x.UserId, x.ModuleId})
    .Select(x=> new {
        x.Key.UserId, 
        x.Key.ModuleId, 
        mask = x.Aggregate(0, (acc, curr)=>acc|curr.BitMaskedPermission)}
     )

答案 1 :(得分:0)

也许是这样的:

PermList p=new PermList();
    var result= (
        from test in p.TestData()
        group test by new{test.UserId,test.ModuleId} into g
        select new
        {
            g.Key.UserId,
            g.Key.ModuleId,
            BitMaskedPermission= g.Sum (x =>x.BitMaskedPermission )
        }
    );