Question

Avez-vous une idée sur la manière de vérifier si cette liste est un sous-ensemble d'un autre?

Plus précisément, j'ai

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

Comment vérifier que t2 est un sous-ensemble de t1 en utilisant LINQ?

Était-ce utile?

La solution

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

Autres conseils

Utilisez HashSet au lieu de List si vous utilisez des ensembles. Ensuite, vous pouvez simplement utiliser IsSubsetOf ()

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

bool isSubset = t2.IsSubsetOf(t1);

Désolé de ne pas utiliser LINQ. : - (

Si vous devez utiliser des listes, la solution de @ Jared fonctionne avec l'avertissement selon lequel vous devrez supprimer tous les éléments répétés existants.

Si vous effectuez des tests unitaires , vous pouvez également utiliser CollectionAssert.IsSubsetOf méthode:

CollectionAssert.IsSubsetOf(subset, superset);

Dans le cas ci-dessus, cela signifierait:

CollectionAssert.IsSubsetOf(t2, t1);

@ La solution de Cameron en tant que méthode d'extension:

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

Utilisation:

bool isSubset = t2.IsSubsetOf(t1);

(Ceci est similaire, mais pas tout à fait identique à celui publié sur le blog de @ Michael)

Il s'agit d'une solution nettement plus efficace que les autres publiées ici, en particulier la solution la plus performante:

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

Si vous pouvez trouver un seul élément dans t2 qui ne soit pas dans t1, alors vous savez que t2 n'est pas un sous-ensemble de t1. L'avantage de cette méthode est que toutes les opérations sont effectuées sur place, sans allouer d'espace supplémentaire, contrairement aux solutions utilisant .Except ou .Intersect. De plus, cette solution est capable de casser dès qu'elle trouve un seul élément qui viole la condition de sous-ensemble, tandis que les autres continuent la recherche. Vous trouverez ci-dessous la forme longue optimale de la solution, qui n’est guère plus rapide dans mes tests que la solution abrégée ci-dessus.

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

J'ai effectué une analyse de performance rudimentaire de toutes les solutions et les résultats sont drastiques. Ces deux solutions sont environ 100 fois plus rapides que les solutions .Except () et .Intersect () et n'utilisent aucune mémoire supplémentaire.

En me basant sur les réponses de @Cameron et de @Neil, j'ai écrit une méthode d'extension qui utilise la même terminologie que la classe Enumerable.

/// <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();
}
  

Ici, nous vérifions que s'il y a un élément présent dans la liste des enfants (c'est-à-dire t2 ) qui n'est pas contenu dans la liste mère (c'est-à-dire t1 ). tel existe alors la liste est sous-ensemble de l'autre

par exemple:

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

Essayez ceci

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

L’idée ici est que Intersect ne renverra que les valeurs qui sont dans les deux tableaux. À ce stade, si la longueur de l'ensemble résultant est la même que celle de l'ensemble d'origine, tous les éléments de "ensemble" sont également dans " check " et donc " set " est un sous-ensemble de "toCheck"

Remarque: ma solution ne fonctionne pas si " set " a des doublons. Je ne le change pas parce que je ne veux pas voler les votes des autres.

Astuce: j'ai voté pour la réponse de Cameron.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top