wake-up-neo.com

Wie kann die Liste A überprüft werden, enthält sie einen beliebigen Wert aus der Liste B?

Liste A: 

1, 2, 3, 4

Liste B: 

2, 5

Wie kann man überprüfen, ob die Liste A einen Wert aus der Liste B enthält?

z.B. etwas wie A.contains (a => a.id = B.id)?

38
wahaha

Wenn Sie sich nicht für die Leistung interessieren, können Sie Folgendes versuchen:

a.Any(item => b.Contains(item))
// or, as in the column using a method group
a.Any(b.Contains)

Aber ich würde das zuerst versuchen:

a.Intersect(b).Any()
69
Justin Niessner

Ich habe Justins zwei Lösungen profiliert.a.Any(a => b.Contains(a)) ist am schnellsten .

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

namespace AnswersOnSO
{
    public class Class1
    {
        public static void Main(string []args)
        {
//            How to check if list A contains any value from list B?
//            e.g. something like A.contains(a=>a.id = B.id)?
            List<int> a = new List<int> {1,2,3,4};
            List<int> b = new List<int> {2,5};
            int times = 10000000;

            DateTime dtAny = DateTime.Now;
            for (int i = 0; i < times; i++)
            {
                var aContainsBElements = a.Any(b.Contains);
            }
            var time = (DateTime.Now - dtAny).TotalSeconds;

            DateTime dt2 = DateTime.Now;
            for (int i = 0; i < times; i++)
            {
                var aContainsBElements = a.Intersect(b).Any();
            }
            var time2 = (DateTime.Now - dt2).TotalSeconds;

            // time1: 1.1470656 secs
            // time2: 3.1431798 sec
        }
    }
}
16
radbyx

Sie können Intersect die beiden Listen:

if (A.Intersect(B).Any())
12
D Stanley

Ich benutze das um zu zählen:

int cnt = 0;

foreach (var lA in listA)
{
    if (listB.Contains(lA))
    {
        cnt++;
    }
}
0
Jan

Ich schreibe eine schnellere Methode, damit sich die kleine einstellen kann. Aber ich teste es in einigen Daten, dass es manchmal schneller ist als Intersect, aber manchmal auch schnell, dass mein Code durchschneidet.

    public static bool Contain<T>(List<T> a, List<T> b)
    {
        if (a.Count <= 10 && b.Count <= 10)
        {
            return a.Any(b.Contains);
        }

        if (a.Count > b.Count)
        {
            return Contain((IEnumerable<T>) b, (IEnumerable<T>) a);
        }
        return Contain((IEnumerable<T>) a, (IEnumerable<T>) b);
    }

    public static bool Contain<T>(IEnumerable<T> a, IEnumerable<T> b)
    {
        HashSet<T> j = new HashSet<T>(a);
        return b.Any(j.Contains);
    }

Die Intersect-Aufrufe Set, bei denen die zweite Größe nicht geprüft wurde, und dies ist der Code des Intersect.

        Set<TSource> set = new Set<TSource>(comparer);
        foreach (TSource element in second) set.Add(element);
        foreach (TSource element in first)
            if (set.Remove(element)) yield return element;

Der Unterschied zwischen zwei Methoden besteht darin, dass meine Methode HashSet verwendet wird. Überprüfen Sie die Anzahl und Intersect verwenden Sie set, die schneller als HashSet ist. Wir kriegen nicht seine Leistung.

Der Test :

   static void Main(string[] args)
    {
        var a = Enumerable.Range(0, 100000);
        var b = Enumerable.Range(10000000, 1000);
        var t = new Stopwatch();
        t.Start();
        Repeat(()=> { Contain(a, b); });
        t.Stop();
        Console.WriteLine(t.ElapsedMilliseconds);//490ms

        var a1 = Enumerable.Range(0, 100000).ToList();
        var a2 = b.ToList();
        t.Restart();
        Repeat(()=> { Contain(a1, a2); });
        t.Stop();

        Console.WriteLine(t.ElapsedMilliseconds);//203ms

        t.Restart();
        Repeat(()=>{ a.Intersect(b).Any(); });
        t.Stop();
        Console.WriteLine(t.ElapsedMilliseconds);//190ms

        t.Restart();
        Repeat(()=>{ b.Intersect(a).Any(); });
        t.Stop();
        Console.WriteLine(t.ElapsedMilliseconds);//497ms

        t.Restart();
        a.Any(b.Contains);
        t.Stop();
        Console.WriteLine(t.ElapsedMilliseconds);//600ms

    }

    private static void Repeat(Action a)
    {
        for (int i = 0; i < 100; i++)
        {
            a();
        }
    }
0
lindexi

Entschuldigung, wenn dies irrelevant ist, wird aber eine Liste mit Übereinstimmungen mit FindAll () zurückgegeben, falls Sie dies benötigen:

        private bool IsContain(string cont)
    {
        List<string> ListToMatch= new List<string>() {"string1","string2"};

        if (ListToMatch.ToArray().Any(cont.Contains))
        {
            return false;
        }
        else
            return true;
    }

Und Verwendung:

List<string> ListToCheck = new List<string>() {"string1","string2","string3","string4"};
List<string> FinalList = ListToCheck.FindAll(IsContain);

Die endgültige Liste enthält nur die übereinstimmenden Elemente string1 und string2 von list bis zur Überprüfung . Kann einfach in int list umgeschaltet werden.

0
Atanas Atanasov