web-dev-qa-db-fra.com

Le contraire de Intersect ()

Intersect peut être utilisé pour trouver des correspondances entre deux collections, comme ceci:

// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call Intersect extension method.
var intersect = array1.Intersect(array2);
// Write intersection to screen.
foreach (int value in intersect)
{
    Console.WriteLine(value); // Output: 2, 3
}

Cependant, ce que j'aimerais réaliser est l'inverse, j'aimerais énumérer les éléments manquants lorsque je compare deux collections:

// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call Intersect extension method.
var intersect = array1.NonIntersect(array2); // I've made up the NonIntersect method
// Write intersection to screen.
foreach (int value in intersect)
{
    Console.WriteLine(value); // Output: 1, 4
}
260
Peter Bridger

Comme indiqué, si vous voulez obtenir 4 comme résultat, vous pouvez faire comme ceci:

var nonintersect = array2.Except(array1);

Si vous voulez la vraie non-intersection (également les deux 1 et 4), alors cela devrait faire l'affaire:

var nonintersect = array1.Except(array2).Union( array2.Except(array1));

Ce ne sera pas la solution la plus performante, mais pour les petites listes, cela devrait fonctionner correctement.

355
Øyvind Bråthen

Vous pouvez utiliser

a.Except(b).Union(b.Except(a));

Ou vous pouvez utiliser

var difference = new HashSet(a);
difference.SymmetricExceptWith(b);
81
sehe

Ce code énumère chaque séquence une seule fois et utilise Select(x => x) pour masquer le résultat afin d'obtenir une méthode d'extension de type Linq propre. Puisqu'il utilise HashSet<T>, son temps d'exécution est O(n + m) si les hachages sont bien distribués. Les éléments en double dans l'une ou l'autre liste sont omis.

public static IEnumerable<T> SymmetricExcept<T>(this IEnumerable<T> seq1,
    IEnumerable<T> seq2)
{
    HashSet<T> hashSet = new HashSet<T>(seq1);
    hashSet.SymmetricExceptWith(seq2);
    return hashSet.Select(x => x);
}
11
CodesInChaos

Je pense que vous cherchez peut-être Except:

L'opérateur Except produit la différence d'ensemble entre deux séquences. Il renverra uniquement les éléments de la première séquence qui n'apparaissent pas à la seconde. Vous pouvez éventuellement fournir votre propre fonction de comparaison d'égalité.

Consultez ce lien , ce lien ou Google pour plus d'informations.

5
Grant Thomas

Je ne suis pas sûr à 100% de ce que votre méthode NonIntersect est censée faire (en ce qui concerne la théorie des ensembles).
B\A (tout de B qui n’apparaît pas dans A)?
Si c'est le cas, vous devriez pouvoir utiliser l'opération Sauf (B.Exception (A)).

2
Frank Schmitt
/// <summary>
/// Given two list, compare and extract differences
/// http://stackoverflow.com/questions/5620266/the-opposite-of-intersect
/// </summary>
public class CompareList
{
    /// <summary>
    /// Returns list of items that are in initial but not in final list.
    /// </summary>
    /// <param name="listA"></param>
    /// <param name="listB"></param>
    /// <returns></returns>
    public static IEnumerable<string> NonIntersect(
        List<string> initial, List<string> final)
    {
        //subtracts the content of initial from final
        //assumes that final.length < initial.length
        return initial.Except(final);
    }

    /// <summary>
    /// Returns the symmetric difference between the two list.
    /// http://en.wikipedia.org/wiki/Symmetric_difference
    /// </summary>
    /// <param name="initial"></param>
    /// <param name="final"></param>
    /// <returns></returns>
    public static IEnumerable<string> SymmetricDifference(
        List<string> initial, List<string> final)
    {
        IEnumerable<string> setA = NonIntersect(final, initial);
        IEnumerable<string> setB = NonIntersect(initial, final);
        // sum and return the two set.
        return setA.Concat(setB);
    }
}
2
alcedo

array1.NonIntersect (array2);

Un autre opérateur qu'un tel opérateur n'est pas présent dans Linq, vous devriez le faire

sauf -> union -> sauf

a.except(b).union(b.Except(a));
1
safder