Побитовая операция с группировкой с использованием Linq - PullRequest
2 голосов
/ 21 февраля 2012

У меня есть данные типа

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

Я хотел бы применить ИЛИ к BitMaskedPermissions с группировкой ModuleId. Вот что я хотел бы получить;

enter image description here

Как мне добиться этого с помощью Linq.

ТИА.

Ответы [ 2 ]

4 голосов
/ 21 февраля 2012

Если у вас есть операция агрегирования, которая не является одной из встроенных (Sum, Max и т. Д.), Вы должны обратиться к 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, и побитовое ИЛИ для получения текущего значения аккумулятора.

Если вы предпочитаете синтаксис цепочки методов, он будет выглядеть (любезно предоставлено @ 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)}
     )
0 голосов
/ 21 февраля 2012

Может быть, что-то вроде этого:

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 )
        }
    );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...