2017-06-21 36 views
1

我想创建一个新的,删除的,公共项目的分组列表。我目前这样做:有没有更有效的方法来创建一个分组列表

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); 

    } 
} 

This works。但我想知道是否有更好或更有效的方法?

最终我希望在WPF分组列表视图中绑定到此。

回答

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 
    }); 
+2

梦幻般的答案和证明更有效。我用我的和你的实现跑秒表,结果如下:ME =>执行时间:16954(6ms) YOU =>执行时间:1321(0ms) – John

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(); 
相关问题