是否有更有效的方法来创建分组列表

时间:2017-06-21 07:38:17

标签: linq listview grouping

我想创建一个NEW,DELETED,COM​​MON项目的分组列表。我目前这样做:

public class ListSortingGroupingTest
{
    List<int> OldList = new List<int> { 1, 2, 3, 4, 5 };
    List<int> NewList = new List<int> { 3, 4, 5, 7, 8, 9 };

    public void CreateGroupedList()
    {
        var deleted = OldList.Except(NewList).Select(i => new { Group = "Deleted", Number = i });
        var added = NewList.Except(OldList).Select(i => new { Group = "Added", Number = i});
        var common = NewList.Intersect(OldList).Select(i => new { Group = "Common", Number = i});

        var result = deleted.Union(added).Union(common);

    }
}

这很有效。但我想知道是否有更好或更有效的方式?

最终我希望在WPF Grouped ListView中绑定它。

2 个答案:

答案 0 :(得分:2)

您当前的方法是提取新旧集合(即唯一序列)值之间变化信息的标准和自然方式。由于基于哈希查找的实现,使用的LINQ集合运算符(ExceptIntersect)非常有效。虽然3次调用将在内部创建3个哈希集,但复杂性仍为O(N+M)。唯一的改进是使用Concat而不是Union,因为之前的方法会唯一地分隔值。

更高效的方式(但仍然是O(N+M))可以将旧项和新项连接到指定值是旧还是新的附加属性,然后按值分组并确定添加/删除/共同基于分组计数和内容的状态 - 具有2个值的组是常见的,对于具有单个值的组,添加/删除的组取决于值是新的还是旧的:

var result = OldList.Select(x => new { Value = x, IsNew = false })
    .Concat(NewList.Select(x => new { Value = x, IsNew = true }))
    .GroupBy(x => x.Value)
    .Select(g => new
    {
        Group = g.Count() > 1 ? "Common" : g.First().IsNew ? "Added" : "Deleted",
        Number = g.Key
    });

答案 1 :(得分:0)

试试这个。

var result = OldList.Union(NewList).Select(n => new
        {
            Group = OldList.Contains(n) && NewList.Contains(n) ? "Common" : (OldList.Contains(n)) ? "Deleted" : "Added",
            Number = n
        }).ToList();