Überprüfen Sie, ob die Liste <t> eine andere Liste enthält


93

Ich habe eine Liste solcher Parameter:

public class parameter
{
    public string name {get; set;}
    public string paramtype {get; set;}
    public string source {get; set;}
}

IEnumerable<Parameter> parameters;

Und eine Reihe von Zeichenfolgen, mit denen ich es überprüfen möchte.

string[] myStrings = new string[] { "one", "two"};

Ich möchte die Parameterliste durchlaufen und prüfen, ob die Quelleigenschaft einem der myStrings-Arrays entspricht. Ich kann dies mit verschachtelten foreachs tun, aber ich würde gerne lernen, wie man es auf eine schönere Art und Weise macht, da ich mit linq herumgespielt habe und die Erweiterungsmethoden auf enumerable mag, wie wo usw. verschachtelte foreachs sich einfach falsch anfühlen. Gibt es eine elegantere bevorzugte Methode für linq / lambda / delegete, um dies zu tun?

Vielen Dank

Antworten:


196

Sie können Any()für diese Prüfung ein verschachteltes Element verwenden, das für Folgendes verfügbar ist Enumerable:

bool hasMatch = myStrings.Any(x => parameters.Any(y => y.source == x));

Schneller auf größeren Sammlungen durchführen zu Projekt wäre parameterszu sourceund verwenden Sie dann Intersectdie im Inneren einen verwendet , HashSet<T>um anstelle von O (n ^ 2) für den ersten Ansatz (das Äquivalent von zwei verschachtelten Schleifen) können Sie den Check - in O tun können (n):

bool hasMatch = parameters.Select(x => x.source)
                          .Intersect(myStrings)
                          .Any(); 

Als Nebenkommentar sollten Sie auch Ihre Klassennamen und Eigenschaftsnamen groß schreiben, um den Richtlinien im C # -Stil zu entsprechen.


Danke scheint das zu sein, wonach ich suche. Ich werde es ausprobieren. Ich muss ein bisschen mehr mit der funktionalen Seite der Dinge herumspielen. In Bezug auf die Großschreibung von Klasse und Eigenschaften wurde ich gerade vergessen, als ich das obige Beispiel schrieb.
GDP

1
Warum O (n ^ 2)? Ist es nicht O (n * m), wenn wir über zwei Variablen sprechen und nicht über eine? Da m (die Parameter) eine Konstante sind, ist es dasselbe wie O (n). Ich sehe nicht, wie Schnittpunkte hier viel schneller sein sollten? Aber vereinbart, hat Intersect das Potenzial, schneller zu sein, ist aber nicht garantiert.
Squazz

Sie haben Recht, dass es O (n * m) sein sollte - m ist jedoch keine Konstante - es ist die Größe einer der Listen, obwohl es in dem gegebenen Beispiel "2" sein könnte. Selbst konstante Werte sind in der Praxis nicht zu vernachlässigen - für alle nicht trivialen Listenlängen Intersectist dies schneller - wenn die Listen trivial kurz sind, spielt dies auf die eine oder andere Weise keine Rolle (in diesem Fall ist die Leistung wahrscheinlich sowieso nicht Ihr Anliegen )
BrokenGlass

Wie können Sie den Listenindex herausfinden, in dem die Bedingung erfüllt wird? Ich habe eine Liste mit Sätzen. Ich habe ein Array mit bestimmten Wörtern. Ich möchte Indizes der Liste, wenn der Satz mindestens ein Wort aus dem Array enthält. @BrokenGlass
Kirushan

1
Wäre die Leistung nicht parameters.Any(x => myStrings.Contains(x.source));besser als Ihr erstes Beispiel?
Fluppe

3

Hier ist ein Beispiel, um festzustellen, ob Übereinstimmungselemente in einer anderen Liste vorhanden sind

List<int> nums1 = new List<int> { 2, 4, 6, 8, 10 };
List<int> nums2 = new List<int> { 1, 3, 6, 9, 12};

if (nums1.Any(x => nums2.Any(y => y == x)))
{
    Console.WriteLine("There are equal elements");
}
else
{
    Console.WriteLine("No Match Found!");
}

2
Beachten Sie, dass wenn die beteiligten Listen groß sind, dies viel langsamer als der IntersectAnsatz ist, da es in den Größen der Listen O (N * M) ist. (Es ist O (1) in Erinnerung.)
Jon Skeet

1

Wenn beide Listen zu groß sind und wir den Lamda-Ausdruck verwenden, dauert das Abrufen lange. Verwenden Sie in diesem Fall besser linq, um die Parameterliste abzurufen:

var items = (from x in parameters
                join y in myStrings on x.Source equals y
                select x)
            .ToList();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.