Frage

Jede Idee, wie Sie überprüfen, ob diese Liste eine Teilmenge eines anderen ist?

Im Einzelnen habe ich

List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };

Wie diese t2 zu überprüfen, ist eine Teilmenge von t1, mit LINQ?

War es hilfreich?

Lösung

bool isSubset = !t2.Except(t1).Any();

Andere Tipps

Verwenden HashSet statt Liste, wenn mit Datensätzen arbeiten. Dann können Sie einfach IsSubsetOf ()

HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};

bool isSubset = t2.IsSubsetOf(t1);

Es tut uns Leid, dass es nicht LINQ nicht verwendet. : - (

Wenn Sie eine Liste verwenden müssen, dann @ Jared Lösung mit dem Vorbehalt, arbeitet, dass Sie benötigen keine wiederholten Elemente zu entfernen, die vorhanden sind.

Wenn Sie unit-testing Sie können auch die CollectionAssert.IsSubsetOf Methode:

CollectionAssert.IsSubsetOf(subset, superset);

Im obigen Fall würde dies bedeuten:

CollectionAssert.IsSubsetOf(t2, t1);

@ Camerons Lösung als Erweiterung Methode:

public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
    return !a.Except(b).Any();
}

Verbrauch:

bool isSubset = t2.IsSubsetOf(t1);

(Dies ist ähnlich, aber nicht ganz dasselbe wie die auf @ Michaels Blog veröffentlicht)

Dies ist eine wesentlich effizientere Lösung als die andere hier geschrieben, vor allem der Top-Lösung:

bool isSubset = t2.All(elem => t1.Contains(elem));

Wenn Sie ein einzelnes Element in t2 finden können, die nicht in t1 ist, dann wissen Sie, dass T2 nicht eine Teilmenge von t1 ist. Der Vorteil dieser Methode ist, dass es an Ort und Stelle durchgeführt wird, ohne zusätzlichen Platz Zuteilung, im Gegensatz zu den Lösungen .except oder .Intersect verwenden. Darüber hinaus ist diese Lösung so schnell brechen kann, wie es ein einzelnes Element findet, die die Teilmenge Bedingung verletzt, während die anderen Benutzer weiter. Unten ist die optimale Lang Form der Lösung, die nur geringfügig schneller in meinen Tests als die oben Stenografie Lösung ist.

bool isSubset = true;
foreach (var element in t2) {
    if (!t1.Contains(element)) {
        isSubset = false;
        break;
    }
}

Ich habe einige rudimentäre Performance-Analyse aller Lösungen, und die Ergebnisse sind drastisch. Diese beiden Lösungen sind über 100x schneller als die .except () und .Intersect () -Lösungen, und verwenden Sie keinen zusätzlichen Speicher.

Basierend auf den Antworten von @Cameron und @Neil ich eine Verlängerung Methode geschrieben, die die gleiche Terminologie wie die Enumerable-Klasse verwendet.

/// <summary>
/// Determines whether a sequence contains the specified elements by using the default equality comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence in which to locate the values.</param>
/// <param name="values">The values to locate in the sequence.</param>
/// <returns>true if the source sequence contains elements that have the specified values; otherwise, false.</returns>
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> values)
{
    return !values.Except(source).Any();
}
  

Hier prüfen wir, dass, wenn es irgendein Element in der Child-Liste ist (das heißt t2), die nicht von der übergeordneten Liste (das heißt t1) .Wenn keine enthalten ist, so besteht dann die Liste Teilmenge der anderen

Beispiel:

bool isSubset = !(t2.Any(x => !t1.Contains(x)));

Versuchen Sie, diese

static bool IsSubSet<A>(A[] set, A[] toCheck) {
  return set.Length == (toCheck.Intersect(set)).Count();
}

Die Idee dabei ist, dass Intersect nur die Werte zurück, die in den beiden Arrays sind. An diesem Punkt, wenn die Länge des resultierenden Satzes das gleiche wie das Original-Set ist, dann wird alle Elemente in „Set“ sind auch in „check“ und deshalb „Set“ ist eine Untergruppe von „toCheck“

Hinweis: Meine Lösung funktioniert nicht, wenn „set“ Duplikate hat. Ich ändere es nicht, weil ich nicht will anderen Leuten Stimmen stehlen.

Hinweis: Ich für Camerons Antwort gestimmt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top