it-swarm.com.de

so prüfen Sie, ob das Objekt bereits in einer Liste vorhanden ist

Ich habe eine liste

  List<MyObject> myList

und ich füge Elemente zu einer Liste hinzu und ich möchte überprüfen, ob das Objekt bereits in der Liste enthalten ist. 

also bevor ich das tue:

 myList.Add(nextObject);

ich möchte sehen, ob nextObject bereits in der Liste enthalten ist. 

das Objekt "MyObject" verfügt über eine Reihe von Eigenschaften, der Vergleich basiert jedoch auf dem Abgleich zweier Eigenschaften.

was ist der beste Weg, um einen Check durchzuführen, bevor ich ein neues "MyObject" zu seiner Liste von "MyObjects" hinzufüge

die einzige Lösung, die ich mir ausgedacht hatte, war, von einer Liste zu einem Wörterbuch zu wechseln, und sie machen den Schlüssel zu einer verketteten Zeichenfolge der Eigenschaften (dies scheint ein wenig unelegant zu sein).

irgendwelche anderen Reinigerlösungen mit list oder LINQ oder etwas anderem?

70
leora

Das hängt von den Bedürfnissen der jeweiligen Situation ab. Zum Beispiel wäre der Wörterbuchansatz ziemlich gut, wenn man annimmt:

  1. Die Liste ist relativ stabil (nicht viele Einfügungen/Löschungen, für die Wörterbücher nicht optimiert sind)
  2. Die Liste ist ziemlich groß (ansonsten ist der Aufwand des Wörterbuchs sinnlos).

Wenn die oben genannten nicht für Ihre Situation zutreffen, verwenden Sie einfach Any() :

Item wonderIfItsPresent = ...
bool containsItem = myList.Any(item => item.UniqueProperty == wonderIfItsPresent.UniqueProperty);'

Dadurch wird die Liste durchlaufen, bis eine Übereinstimmung gefunden wird oder das Ende erreicht wird.

113
Rex M

Verwenden Sie einfach Enthält Methode. Beachten Sie, dass es auf der Gleichheitsfunktion Equals basiert. 

bool alreadyExist = list.Contains(item);
60
Ahmad

Wenn diese 2 Eigenschaften verwendet werden können, können Sie Folgendes tun:

bool alreadyExists = myList.Any(x=> x.Foo=="ooo" && x.Bar == "bat");
44
p.campbell

Sind Sie sicher, dass Sie in diesem Fall eine Liste benötigen? Wenn Sie die Liste mit vielen Elementen füllen, leidet die Leistung unter myList.Contains oder myList.Any; Die Laufzeit wird quadratisch sein. Möglicherweise möchten Sie eine bessere Datenstruktur in Betracht ziehen. Zum Beispiel,

 public class MyClass
    {
        public string Property1 { get; set; }
        public string Property2 { get; set; }

    }

    public class MyClassComparer : EqualityComparer<MyClass>
    {
        public override bool Equals(MyClass x, MyClass y)
        {
            if(x == null || y == null)
               return x == y;

            return x.Property1 == y.Property1 && x.Property2 == y.Property2;
        }

        public override int GetHashCode(MyClass obj)
        {
            return obj == null ? 0 : (obj.Property1.GetHashCode() ^ obj.Property2.GetHashCode());
        }
    }

Sie können ein HashSet auf folgende Weise verwenden:

  var set = new HashSet<MyClass>(new MyClassComparer());
  foreach(var myClass in ...)
     set.Add(myClass);

Wenn diese Definition der Gleichheit für MyClass 'universal' ist, müssen Sie natürlich keine IEqualityComparer-Implementierung schreiben. Sie könnten einfach GetHashCode und Equals in der Klasse selbst überschreiben.

6
Ani

Ein weiterer wichtiger Punkt ist, dass Sie sicherstellen sollten, dass Ihre Gleichstellungsfunktion Ihren Erwartungen entspricht. Sie sollten die equals-Methode überschreiben, um festzulegen, welche Eigenschaften Ihres Objekts übereinstimmen müssen, damit zwei Instanzen als gleich betrachtet werden.

Dann können Sie einfach Mylist.contains (item) machen

Edit: Ich hatte zuerst gesagt:


Was ist unelegant über die Wörterbuchlösung? Es erscheint mir vollkommen elegant, zumal Sie bei der Erstellung des Wörterbuchs nur den Vergleicher einstellen müssen.


Natürlich ist es unerheblich, etwas als Schlüssel zu verwenden, wenn es auch der Wert ist.

Daher würde ich ein HashSet verwenden. Wenn für spätere Vorgänge eine Indizierung erforderlich war, würde ich nach dem Hinzufügen eine Liste erstellen, andernfalls verwenden Sie einfach das Hashset.

3
Jon Hanna

Hier ist eine schnelle Konsolen-App, um das Konzept der Problemlösung darzustellen.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    public class myobj
    {
        private string a = string.Empty;
        private string b = string.Empty;

        public myobj(string a, string b)
        {
            this.a = a;
            this.b = b;
        }

        public string A
        {
            get
            {
                return a;
            }
        }

        public string B
        {
            get
            {
                return b;
            }
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            List<myobj> list = new List<myobj>();
            myobj[] objects = { new myobj("a", "b"), new myobj("c", "d"), new myobj("a", "b") };


            for (int i = 0; i < objects.Length; i++)
            {
                if (!list.Exists((delegate(myobj x) { return (string.Equals(x.A, objects[i].A) && string.Equals(x.B, objects[i].B)) ? true : false; })))
                {
                    list.Add(objects[i]);
                }
            }
        }
    }
}

Genießen!

3
Doug

Einfach, aber es funktioniert

MyList.Remove(nextObject)
MyList.Add(nextObject)

oder

 if (!MyList.Contains(nextObject))
    MyList.Add(nextObject);
0
Opt Prutal