web-dev-qa-db-fra.com

Rechercher un élément dans ObservableCollection sans utiliser de boucle

Actuellement, j'ai la syntaxe suivante (list est une liste contenant des objets avec beaucoup de propriétés différentes (où Title en est un):

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

Comment puis-je accéder au list[i].Title sans avoir à parcourir toute ma collection? Étant donné que ma liste tend à prendre de l'ampleur, cela peut avoir une incidence sur les performances de mon programme.

J'ai beaucoup de syntaxe similaire dans mon programme (accès aux propriétés publiques via une boucle for et par index). Mais je suis sûr qu'il doit y avoir un moyen meilleur et élégant de le faire?

La méthode find semble être une option puisque ma liste contient des objets.

25
PeterP

Je ne sais pas ce que tu veux dire exactement, mais techniquement, ce n'est pas possible sans une boucle. 

Peut-être que vous voulez dire en utilisant un LINQ, comme par exemple: 

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

Il est à noter que l'itération terminée n'est pas ignorée, mais simplement incluse dans la requête LINQ.

J'espère que cela t'aides.

MODIFIER 

En d'autres termes, si vous êtes {vraiment} préoccupé par les performances, continuez à coder comme vous le faites déjà. Sinon, choisissez LINQ pour une syntaxe plus concise et claire.

42
Tigran

Voici Linq:

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

Il lève une exception s'il n'y a pas d'élément correspondant au prédicat. Sinon, il y a SingleOrDefault.

Si vous voulez une collection d'éléments correspondant au titre, il y a:

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

je devais l'utiliser pour une condition ajouter si vous n'avez pas besoin de l'index

using System.Linq;

utilisation

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

cela vous dira si une variable satisfait votre condition donnée.

5
haxpak

Envisagez de créer un index. Un dictionnaire peut faire l'affaire. Si vous avez besoin de la sémantique de la liste, sous-classez et conservez l'index comme membre privé ...

3
Daren Thomas

Je suggérerais de les stocker dans une table de hachage. Vous pouvez ensuite accéder à un élément de la collection à l'aide de la clé. Il s'agit d'une recherche beaucoup plus efficace.

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

Vous recherchez une collection basée sur le hachage (comme un dictionnaire ou un hachage), ce que l'ObservableCollection n'est pas. La meilleure solution pourrait être de dériver d'une collection basée sur un hachage et d'implémenter INotifyCollectionChanged, ce qui vous donnera le même comportement qu'une ObservableCollection.

1
Dan Busha

ObservableCollection est une liste. Par conséquent, si vous ne connaissez pas la position de l'élément, vous devez examiner chaque élément jusqu'à ce que vous trouviez l'élément attendu.

Optimisation possible Si vos éléments sont triés, utilisez une recherche binaire pour améliorer les performances, sinon utilisez un Dictionnaire comme index.

1
Roberto

Eh bien, si vous avez N objets et que vous devez obtenir le titre de tous, vous devez utiliser une boucle. Si vous avez seulement besoin du titre et que vous voulez vraiment l'améliorer, vous pouvez peut-être créer un tableau séparé contenant uniquement le titre, cela améliorerait les performances .. vous pouvez gérer avant de dire que cela peut nuire aux performances, et dans tous les cas, la solution changerait la conception du programme et non de l'algorithme.

0
memo

Peut-être que cette approche résoudrait le problème:

int result = obsCollection.IndexOf(title);

IndexOf (T)
Recherche l'objet spécifié et retourne l'index de base zéro de la première occurrence dans toute la collection.

(Hérité de Collection)

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

0
mjordan