3

過去 x か月間に仕事が予約されていないかどうかに基づいて、クライアントのリストをフィルタリングする必要があります。私のコードには 2 つのリストがあります。1 つはクライアントで、もう 1 つは今日から x か月前までのフィルター処理されたジョブのリストであり、ジョブ リストに表示されない ID に基づいてクライアントをフィルター処理するというアイデアです。私は次のことを試しました:

filteredClients.Where(n => jobsToSearch.Count(j => j.Client == n.ClientID) == 0).ToList();

しかし、関係なくすべてのクライアントを取得しているようです。foreach は簡単に実行できますが、これによりプロセスが大幅に遅くなります。ジョブリストに基づいてクライアントリストを効果的にフィルタリングするにはどうすればよいですか?

4

3 に答える 3

3

あなたが間違っている主なことは、結果を何かに割り当てないことです。そのため、元のクライアントはすべてのクライアントを保持しているように見えました。しかし、オリジナルを改善することはできます。

filteredClients = filteredClients.Where(n => !jobsToSearch.Any(j => j.Client == n.ClientId)).ToList();

.Count()これとあなたのソリューションの違いは.Any()、最初の一致に遭遇するとすぐに各クライアントでジョブ リストの参照を停止できるため、実行速度が少し速くなることです。しかし、まだ終わりではありません。ジョブリストを個別のクライアントのみに絞り込むことで、さらにうまくいくことができます。

var badClients = jobsToSearch.Select(j => j.Client).Distinct().ToList();
filteredClients = filteredClients.Where(n => !badClients.Any(j => j == n.ClientId)).ToList();

そして、Dcitionary のように O(1) ルックアップを作成できるHashSetを使用すると、おそらくさらに良いでしょう。クライアント ID が int であると仮定します。

 var badClients = new HashSet<int>(jobsToSearch.Select(j => j.Client));
 filteredClients = filteredClients.Where(n => !badClients.Contains(n.ClientId)).ToList();

この最後のオプションのパフォーマンスが向上するかどうかは、ジョブを持つクライアントの数に依存します...リストが短い場合でも、.Distinct() の方がパフォーマンスが向上する可能性があります。

最後に、通常、このような呼び出しはお勧めしません.ToList()。リスト、配列、またはコレクション型を実際に実現することは可能な限り最後の瞬間まで保存し、できるだけ長く Enumerable に保持します。

于 2012-12-17T22:45:50.110 に答える
1

「groupby」の使用について考えましたか?

構文をチェックせずにコードを書いても頭から離れません (havnt と利用可能な atm):

var groupedJobs = jobsearch.GroupBy(job => job.Client);
var itemsWithJobs = filteredList.Where(item => groupedJobs.ContainsKey(item.ClientID));

明日の朝、構文を確認できます。

これの最大の長所は、検索がはるかに高速な辞書を作成したことです。リストを反復するよりも。

于 2012-12-17T22:45:17.097 に答える
0

inIdListであるクライアントをフィルタリングするには;

List1.Where(x=> IdList.Contains(x.ClientId));

not inIdListであるクライアントをフィルタリングするには;

List1.Where(x=> !IdList.Contains(x.ClientId));
于 2012-12-17T22:42:11.440 に答える