5

フィルタリングにmyFiltersを使用してmyCollectionから要素を選択したい:

var myFilters = new List<string> {"111", "222"};
var myCollection = new List<SomeClass> {
                      new SomeClass ("111"), 
                      new SomeClass ("999")
                   };

from filter in myFilters
from item in myCollection
where item.Name == filter
select item

「111」アイテムを返します。

ただし、myFiltersが空の場合は、myCollectionからすべてのアイテムを返します。

var myFilters = new List<string> ();
var myCollection = new List<SomeClass> {
                          new SomeClass ("111"), 
                          new SomeClass ("999")
                    };

// Here's where I'm lost...
from filter in myFilters
from item in myCollection
where item.Name == filter
select item

すべてのアイテム(「111」と「999」)を返します。

4

5 に答える 5

8

これらのコレクションのサイズが大きくなる場合は、結合を使用することをお勧めします。次のようになります。

var result = 
    myFilters.Any() ?
        from item in myCollection
        join filter in myFilters
        on item.Name equals filter into gj
        where gj.Any()
        select item
    : myCollection;

結合を使用する機会は簡単に見落とされます。この結合アプローチは、リストがリモートで大きい場合、containsアプローチよりもパフォーマンスが高くなります。それらが小さく、パフォーマンスが許容できる場合は、最も明確と思われる方を使用してください。

于 2012-09-13T01:17:17.130 に答える
5
var result = myCollection
                   .Where(i => (!myFilters.Any() || myFilters.Contains(i.Name)));
于 2012-09-13T04:45:40.903 に答える
2

できる最善のことは、フィルターをSomeClassに投影することです。何かのようなもの:

var results = myCollection.Any() ?
    myCollection.Where(item => myFilters.Contains(item.Name)) :
    myFilters.Select(f => new SomeClass (f));
于 2012-09-13T00:46:12.777 に答える
0

これはどう?

var myFilters = new List<string> ();
var myCollection = new List<SomeClass> {new SomeClass ("111"), new SomeClass ("999")};

// Here's where I'm lost...
from filter in myFilters
from item in myCollection
where item.Name == filter || !myFilters.Any()
select item

2つのコレクションから選択すると、where句に基づいて結合が実行されます。上記の結合条件は、item.Nameがfilterに等しいか、使用可能なフィルターがない場合はそれを選択することを示しています。

于 2012-09-13T01:24:53.477 に答える
0

これを試して:

var result = myCollection.Where(s => !myFilters.Any() ||
                                     myFilters.Contains(s.Name));
//EDIT: commented these lines..based on comment by @Servy
//var result = myCollection.Where(s => myFilters.Count == 0 ||
//                                     myFilters.Contains(s.Name));

たぶん、フィルターコレクションを1回だけカウントする方がよいでしょう。

bool isFilterEmpty = !myFilters.Any(); 
//bool isFilterEmpty = myFilters.Count == 0;    //...or like this
var result = myCollection.Where(s => isFilterEmpty || 
                                     myFilters.Contains(s.Name));

編集

@ itsme86の答えは正しいと言ってもいいでしょうが、彼はあなたのコレクションを混乱させていると思います。したがって、彼の答えはどういうわけか次のようになります。

var results = myFilters.Any()
                 ? myCollection.Where(item => myFilters.Contains(item.Name))
                 : myCollection;
于 2012-09-13T00:58:20.910 に答える