2017-06-21 13 views
1

NEW、DELETED、COMMONアイテムのグループ化されたリストを作成したいと思います。私は現在次のようにしています。グループ化されたリストを作成するより効率的な方法はありますか

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

あなたの現在のアプローチは、値の古いセットと新しいセット(すなわちユニークなシーケンス)の間の変更についての情報を抽出する標準的かつ自然な方法です。使用されるLINQセット演算子(ExceptおよびIntersect)は、ハッシュ検索ベースの実装のために非常に効率的です。 3回の呼び出しで内部的に3つのハッシュセットが作成されますが、複雑さはまだO(N+M)です。以前の方法で一意に値を分離するため、唯一の改善点はUnionの代わりにConcatを使用することです。

ビットより効率的な方法(まだ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(); 
関連する問題