2017-03-10 3 views
0

現在、私は、linqを使用して別のコレクションに存在しないアイテムをフィルタリングする方法について効率的なソリューションを探しています。 は、これまでのところ私は、次のオプションのところに来:他のコレクションに存在しないアイテムを1つのコレクションにフィルタリングする方法 - LINQ way

class ConrolAccount 
     { 
      public string ControlName { get; set; } 

      public string NaturalAccount { get; set; } 
     } 

     static void Main(string[] args) 
     { 
      var defaultAccounts = new List<ConrolAccount> 
      { 
       new ConrolAccount {NaturalAccount = "71300", ControlName = "Income Control"}, 
       new ConrolAccount {NaturalAccount = "70900", ControlName = "AP Control"}, 
       new ConrolAccount {NaturalAccount = "71600", ControlName = "Cost Control"}, 
       new ConrolAccount {NaturalAccount = "20200", ControlName = "Trust Control"}, 
       new ConrolAccount {NaturalAccount = "71800", ControlName = "Tax Control"}, 
       new ConrolAccount {NaturalAccount = "72000", ControlName = "Undeposited Funds"} 
      }; 

      var existingAccounts = new List<ConrolAccount> 
      { 
       new ConrolAccount {NaturalAccount = "70900", ControlName = "AP Control"}, 
       new ConrolAccount {NaturalAccount = "71600", ControlName = "Cost Control"}, 
       new ConrolAccount {NaturalAccount = "72000", ControlName = "Undeposited Funds"} 
      }; 

      IEnumerable<string> missedAccounts = defaultAccounts 
       .GroupJoin(existingAccounts, d => d.ControlName, e => e.ControlName, (d, accounts) => new {d, accounts}) 
       .Where(a => !a.accounts.Any()) 
       .Select(a => a.d.ControlName); 

      foreach (string controlName in missedAccounts) 
      { 
       Console.WriteLine(controlName); 
      } 

      Console.WriteLine(); 
     } 

この意志出力:http://rextester.com/EBLZ71941

インカムコントロール 信託コントロール 税コントロール

がここサンドボックスへのリンクがあります

linqで効率を上げることはできますか?または誰かがlinqを使用せずにより高速なアルゴリズムを提案することができますか?

+1

を見つけ、このソリューションは思わいいよ。コレクションを二次的に列挙するのではなく、アカウントの合計で線形に近くなければなりません(私は推測します)。しかし、実際には 'ControlName'値だけが必要なので、これを統語的に改善することができます。 –

答えて

1

あなたはControlNameプロパティにのみ関心があるので、Exceptは、より効率的である:

IEnumerable<string> missedAccounts = defaultAccounts.Select(a => a.ControlName) 
    .Except(existingAccounts.Select(a => a.ControlName)); 
0

あなたはおよそIntersect()Except()事前に定義された機能を知っていますか?

Intersect() - 二つのリスト/コレクション間で

Except()を共通項目を見つける - パフォーマンスの面では最初のコレクション内の項目を除いた項目(順番どおりに定義)

関連する問題