web-dev-qa-db-ja.com

ループを使用せずにObservableCollectionでアイテムを検索する

現在、私は次の構文を持っています(リストは多くの異なるプロパティを持つオブジェクトを含むリストです(タイトルはそれらの1つです):

for (int i=0; i < list.Count; i++)
{
   if(title == list[i].Title)
   {
    //do something
   }
}

コレクション全体をループせずにlist[i].Titleにアクセスするにはどうすればよいですか?リストが大きくなる傾向があるため、これはプログラムのパフォーマンスに影響を与える可能性があります。

私はプログラム全体で同様の構文をたくさん持っています(forループおよびインデックスによってパブリックプロパティにアクセスします)。しかし、これを行うためのより優れたエレガントな方法があるはずだと確信していますか?

リストにはオブジェクトが含まれているため、findメソッドはオプションのようです。

27
PeterP

私はあなたが何を意味するのかわかりません正確に、しかし技術的に言えば、これは不可能ですなしループ。

たとえば、次のようにLINQを使用することを意味する場合があります。

list.Where(x=>x.Title == title)

繰り返しをスキップするのではなく、単にLINQクエリにラップすることに言及する価値があります。

お役に立てれば。

[〜#〜] edit [〜#〜]

言い換えれば、reallyパフォーマンスを懸念している場合は、既に行っている方法でコーディングを続けてください。それ以外の場合は、より簡潔で明確な構文のためにLINQを選択します。

43
Tigran

Linqが登場:

var listItem = list.Single(i => i.Title == title);

述語に一致するアイテムがない場合、例外をスローします。または、SingleOrDefaultがあります。

タイトルに一致するアイテムのコレクションが必要な場合は、次のものがあります。

var listItems = list.Where(i => i.Title ==  title);
32
Patryk Ćwiek

インデックスが必要ない場合は、条件の追加に使用する必要がありました

using System.Linq;

つかいます

if(list.Any(x => x.Title == title){
// do something here
}

これにより、変数が指定の条件を満たすかどうかがわかります。

5
haxpak

インデックスの作成を検討してください。辞書がトリックを行うことができます。リストのセマンティクスが必要な場合、サブクラスを作成し、インデックスをプライベートメンバーとして保持します...

3
Daren Thomas

これらをハッシュテーブルに保存することをお勧めします。その後、キーを使用してコレクション内のアイテムにアクセスできます。これは、はるかに効率的な検索です。

var myObjects = new Hashtable();
myObjects.Add(yourObject.Title, yourObject);
...
var myRetrievedObject = myObjects["TargetTitle"];
3
used2could

ObservableCollectionではないハッシュベースのコレクション(DictionaryやHashsetなど)を探しています。最善の解決策は、ハッシュベースのコレクションから派生し、INotifyCollectionChangedを実装することです。これにより、ObservableCollectionと同じ動作が得られます。

1
Dan Busha

ObservableCollectionはリストであるため、要素の位置がわからない場合は、予想される要素が見つかるまで各要素を調べる必要があります。

可能な最適化要素がソートされている場合は、バイナリ検索を使用してパフォーマンスを改善し、そうでない場合はインデックスとして辞書を使用します。

1
Roberto

N個のオブジェクトがあり、それらすべてのタイトルを取得する必要がある場合は、ループを使用する必要があります。タイトルのみが必要で、これを本当に改善したい場合は、タイトルのみを含む分離された配列を作成すると、パフォーマンスが向上します。これがパフォーマンスを損なう可能性があると言う前に、使用可能なメモリの量と処理できるオブジェクトの量を定義する必要があります。いずれにしても、解決策はアルゴリズムではなくプログラムの設計を変更することです。

0
memo

たぶん、このアプローチは問題を解決するでしょう:

int result = obsCollection.IndexOf(title);

IndexOf(T)
指定されたオブジェクトを検索し、コレクション全体で最初に出現したゼロから始まるインデックスを返します。

(コレクションから継承)

https://docs.Microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netframework-4.7.2#methods

0
mjordan