it-swarm.com.de

Überprüfen Sie, ob zwei Listen gleich sind

Ich habe eine Klasse wie folgt:

public class Tag {
    public Int32 Id { get; set; }
    public String Name { get; set; }
}

Und ich habe zwei Listen mit Tags:

List<Tag> tags1;
List<Tag> tags2;

Ich habe LINQ verwendet, um die IDs der einzelnen Tags zu ermitteln. Und dann:

List<Int32> ids1 = new List<Int32> { 1, 2, 3, 4 };
List<Int32> ids2 = new List<Int32> { 1, 2, 3, 4 };
List<Int32> ids3 = new List<Int32> { 2, 1, 3, 4 };
List<Int32> ids4 = new List<Int32> { 1, 2, 3, 5 };
List<Int32> ids5 = new List<Int32> { 1, 1, 3, 4 };

ids1 sollte gleich ids2 und ids3 sein ... Beide haben die gleichen Nummern.

ids1 sollte nicht gleich ids4 und ids5 sein ...

Ich habe folgendes versucht:

var a = ints1.Equals(ints2);
var b = ints1.Equals(ints3);

Aber beide geben mir falsch.

Was ist der schnellste Weg, um zu überprüfen, ob die Listen der Tags gleich sind?

[~ # ~] Update [~ # ~]

Ich suche POSTS, deren TAGS genau den TAGS in einem BOOK entsprechen.

IRepository repository = new Repository(new Context());

IList<Tags> tags = new List<Tag> { new Tag { Id = 1 }, new Tag { Id = 2 } };

Book book = new Book { Tags = new List<Tag> { new Tag { Id = 1 }, new Tag { Id = 2 } } };

var posts = repository
  .Include<Post>(x => x.Tags)
  .Where(x => new HashSet<Int32>(tags.Select(y => y.Id)).SetEquals(book.Tags.Select(y => y.Id)))
  .ToList();

Ich verwende Entity Framework und erhalte den Fehler:

In mscorlib.dll ist eine Ausnahme vom Typ "System.NotSupportedException" aufgetreten, die jedoch im Benutzercode nicht behandelt wurde

Zusätzliche Informationen: LINQ to Entities erkennt die Methode "Boolean SetEquals (System.Collections.Generic.IEnumerable`1 [System.Int32])" nicht und diese Methode kann nicht in einen Geschäftsausdruck übersetzt werden.

Wie löse ich das?

147
Miguel Moura

Verwenden Sie SequenceEqual , um die Gleichheit der Sequenzen zu überprüfen, da die Equals -Methode die Referenzgleichheit prüft .

var a = ints1.SequenceEqual(ints2);

Oder wenn Ihnen die Reihenfolge der Elemente egal ist, verwenden Sie Enumerable.All Methode:

var a = ints1.All(ints2.Contains);

Die zweite Version erfordert auch eine erneute Prüfung auf Count, da sie auch dann true zurückgeben würde, wenn ints2 enthält mehr Elemente als ints1. Die korrektere Version wäre also ungefähr so:

var a = ints1.All(ints2.Contains) && ints1.Count == ints2.Count;

Um die Ungleichung zu überprüfen , kehren Sie einfach das Ergebnis der All -Methode um:

var a = !ints1.All(ints2.Contains)
270
Selman Genç

List<T> Gleichheit prüft sie nicht Element für Element. Sie können dafür LINQs SequenceEqual -Methode verwenden:

var a = ints1.SequenceEqual(ints2);

Verwenden Sie SetEquals, um die Reihenfolge zu ignorieren:

var a = new HashSet<int>(ints1).SetEquals(ints2);

Dies sollte funktionieren, da Sie Sequenzen von IDs vergleichen, die keine Duplikate enthalten. Wenn dies der Fall ist und Sie Duplikate berücksichtigen müssen, müssen Sie in linearer Zeit ein Hash-basiertes Zählwörterbuch erstellen, eins für jedes Element der ersten Sequenz hinzufügen und eins für jedes Element der zweiten Sequenz subtrahieren Sequenz, und überprüfen Sie, ob die resultierenden Zählungen alle Nullen sind:

var counts = ints1
    .GroupBy(v => v)
    .ToDictionary(g => g.Key, g => g.Count());
var ok = true;
foreach (var n in ints2) {
    int c;
    if (counts.TryGetValue(n, out c)) {
        counts[n] = c-1;
    } else {
        ok = false;
        break;
    }
}
var res = ok && counts.Values.All(c => c == 0);

Wenn Sie mit einer O(N*LogN) -Lösung zufrieden sind, können Sie die beiden Sequenzen sortieren und mit SequenceEqual auf Gleichheit vergleichen.

103
dasblinkenlight
Enumerable.SequenceEqual(FirstList.OrderBy(fElement => fElement), 
                         SecondList.OrderBy(sElement => sElement))
24
Pankaj