仅从列表中获取唯一元素

时间:2013-12-22 00:16:31

标签: c# linq list group-by unique

列出包含deviceIds的列表以及要在设备上执行的相应操作。

var results= new List<Result>
{
    new Result{ DeviceId= 1, ActionType = 1 },
    new Result{ DeviceId= 1, ActionType = 2 },
    new Result{ DeviceId= 1, ActionType = 3 },
    new Result{ DeviceId= 2, ActionType = 1 },
    new Result{ DeviceId= 3, ActionType = 1 },
    new Result{ DeviceId= 4, ActionType = 1 },
    new Result{ DeviceId= 5, ActionType = 1 },
    new Result{ DeviceId= 6, ActionType = 1 },
    new Result{ DeviceId= 6, ActionType = 2 },

};

如何过滤列表中唯一的deviceIds(无DeviceId 1),并将其分配回var“results”

results = List<Result>
{
    new Result{ DeviceId= 2, ActionType = 1 },
    new Result{ DeviceId= 3, ActionType = 1 },
    new Result{ DeviceId= 4, ActionType = 1 },
    new Result{ DeviceId= 5, ActionType = 1 },
};

尝试过使用groupby而无法继续前进

   results =  from result in results
              group result by result.DeviceId
              into groupedResultsByDevice
              where groupedResultsByDevice.Count() == 1
              select ????

4 个答案:

答案 0 :(得分:1)

results =  from r in results
           group r by r.DeviceId into g
           where g.Count() == 1
           select g.First()

您可以使用g.Count()替换!g.Skip(1).Any()来提高效率:

results =  from r in results
           group r by r.DeviceId into g
           where !g.Skip(1).Any()
           select g.First()

一旦找到第二个元素,它将返回false,而不是计算组中的所有项目。

答案 1 :(得分:1)

分组后,您可以选择第一个(也是该组的唯一元素):

results =  from result in results
          group result by result.DeviceId
          into groupedResultsByDevice
          where groupedResultsByDevice.Count() == 1
          select groupedResultsByDevice.First(); // <---

答案 2 :(得分:1)

除了回答查询语法之外,在方法语法LINQ查询中它将是:

results = results.GroupBy(r => r.DeviceId)
                 .Where(g => g.Key != 1 && g.Count() == 1)
                 .Select(g => g.First())
                 .ToList();

答案 3 :(得分:0)

检查出来

    public static void Main()
    {
        var results = new List<Result>
                          {
                              new Result {DeviceId = 1, ActionType = 1},
                              new Result {DeviceId = 1, ActionType = 2},
                              new Result {DeviceId = 1, ActionType = 3},
                              new Result {DeviceId = 2, ActionType = 1},
                              new Result {DeviceId = 3, ActionType = 1},
                              new Result {DeviceId = 4, ActionType = 1},
                              new Result {DeviceId = 5, ActionType = 1},
                              new Result {DeviceId = 6, ActionType = 1},
                              new Result {DeviceId = 6, ActionType = 2},
                          };
        List<Result> result = results
            .GroupBy(x => x.DeviceId)
            .Where(x => x.Count() == 1)
            .SelectMany(x => x)
            .Distinct()
            .ToList();

        result.ForEach(Console.WriteLine);

        Console.ReadLine();
    }

public sealed class Result : IEqualityComparer<Result>
{
    public int DeviceId { get; set; }

    public int ActionType { get; set; }

    public bool Equals(Result x, Result y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return x.DeviceId == y.DeviceId && x.ActionType == y.ActionType;
    }

    public int GetHashCode(Result obj)
    {
        unchecked
        {
            return (obj.DeviceId*397) ^ obj.ActionType;
        }
    }

    public override string ToString()
    {
        return string.Format("DeviceId: {0}, ActionType: {1}", DeviceId, ActionType);
    }
}

结果输出:

DeviceId: 2, ActionType: 1
DeviceId: 3, ActionType: 1
DeviceId: 4, ActionType: 1
DeviceId: 5, ActionType: 1