2017-06-21 62 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(); 
相關問題