Überprüfen Sie, ob die Liste ein Element enthält, das eine Zeichenfolge enthält, und rufen Sie dieses Element ab


146

Auf der Suche nach einer Antwort auf diese Frage bin ich auf ähnliche mit LINQ gestoßen, konnte sie jedoch nicht vollständig verstehen (und somit implementieren), da ich nicht damit vertraut bin. Was ich im Grunde möchte, ist Folgendes:

  1. Überprüfen Sie, ob ein Element einer Liste eine bestimmte Zeichenfolge enthält.
  2. Wenn ja, holen Sie sich dieses Element.

Ich weiß ehrlich gesagt nicht, wie ich das machen würde. Was ich mir einfallen lassen kann, ist Folgendes (funktioniert natürlich nicht):

if (myList.Contains(myString))
    string element = myList.ElementAt(myList.IndexOf(myString));

Ich weiß, warum es nicht funktioniert:

  • myList.Contains()wird nicht zurückgegeben true, da geprüft wird, ob ein ganzes Element der Liste mit der von mir angegebenen Zeichenfolge übereinstimmt.
  • myList.IndexOf() wird kein Vorkommen finden, da es, wie es wieder der Fall ist, nach einem Element sucht, das mit der Zeichenfolge übereinstimmt.

Ich habe noch keine Ahnung, wie ich dieses Problem lösen soll, aber ich denke, ich muss LINQ verwenden, wie in ähnlichen Fragen wie meinen vorgeschlagen. Wenn dies hier der Fall ist, möchte ich, dass der Antwortende mir die Verwendung von LINQ in seinem Beispiel erklärt (wie gesagt, ich habe mich in meiner Zeit mit C # nicht darum gekümmert). Vielen Dank im Voraus Jungs (und Mädels?).

EDIT: Ich habe eine Lösung gefunden; Durchlaufen Sie einfach die Liste, prüfen Sie, ob das aktuelle Element die Zeichenfolge enthält, und setzen Sie dann eine Zeichenfolge, die dem aktuellen Element entspricht. Ich frage mich jedoch, ob es einen effizienteren Weg gibt als diesen?

string myString = "bla";
string element = "";

for (int i = 0; i < myList.Count; i++)
{
    if (myList[i].Contains(myString))
        element = myList[i];
}

Wie ich in meiner Antwort erwähne, sind altmodische Loops (wie Sie sie als Ihre Frage haben) fast immer am schnellsten. Aber Sie könnten es perfekt testen, wenn Sie sich genug interessieren.
McKay

Ihre Liste kann mehrere Zeichenfolgen enthalten, die Ihre Zeichenfolge enthalten myString. In Ihrer aktuellen Schleife erhalten Sie das letzte Element. Es hängt von Ihnen ab, ob Sie den ersten oder den letzten finden möchten. Wenn Sie nur den ersten finden möchten, brechen Sie die Schleife, nachdem Sie den Gegenstand gefunden haben.
Habib

Antworten:


193

Sie sollten Linq hier verwenden können:

var matchingvalues = myList
    .Where(stringToCheck => stringToCheck.Contains(myString));

Wenn Sie einfach den ersten passenden Artikel zurückgeben möchten:

var match = myList
    .FirstOrDefault(stringToCheck => stringToCheck.Contains(myString));

if(match != null)
    //Do stuff

1 - Oder ersetzen Wheremit FirstOrDefaultim zweiten FallmyList.FirstOrDefault(stringToCheck => stringToCheck.Contains(myString))
Habib

Gute Antwort. Nur aus Neugier: Warum ist es vom matchingCompiler bestimmt ( var)? StringWäre es string matchingin diesem Fall sicher , meine Liste zu verwenden , da ich weiß, dass sie vom Typ ist ?
Dimitris Iliadis

1
@JimIliadis "var" und "string" bedeuten in diesem Fall genau dasselbe - der Compiler ist klug genug zu wissen, dass das Ergebnis nur 'string' sein kann. var ist wirklich nur eine Sache im Codierungsstil (wenn keine anonymen Typen verwendet werden)
Dave Bish

zu alten Thread kommentieren, aber eine Ausnahme gefunden. Wenn Sie firstordefault () verwenden, stellen Sie sicher, dass auch der Standardwert zurückgegeben werden kann. Nehmen wir also an, Sie übergeben eine Empy-Zeichenfolge, z. B. mystring = "", und Sie erwarten, dass nichts angezeigt wird. Dennoch wird das erste Element der Liste angezeigt, da Sie firstordefault ausgewählt haben.
Schmutziger Entwickler

@DirtyDeveloper Sie sind sich nicht sicher, was Sie damit meinen. Ihr Beispiel würde 'null' zurückgeben, wenn die Zielliste keine leeren Zeichenfolgen enthält. Sie haben Recht, wenn Sie versuchen, FirstOrDefault () für einen Strukturtyp zu verwenden, z. B. List <int> - FirstOrDefault () gibt '0' und nicht null zurück. Die Frage betraf jedoch speziell Zeichenfolgen
Dave Bish

29

Die grundlegende Antwort lautet: Sie müssen die Schleife durchlaufen und überprüfen, ob ein Element die angegebene Zeichenfolge enthält. Nehmen wir also an, der Code lautet:

foreach(string item in myList)
{
    if(item.Contains(myString))
       return item;
}

Der äquivalente, aber knappe Code lautet:

mylist.Where(x => x.Contains(myString)).FirstOrDefault();

Hier ist x ein Parameter, der sich im obigen Code wie "item" verhält.


12
string result = myList.FirstOrDefault(x => x == myString)
if(result != null)
{
  //found
}

9
for (int i = 0; i < myList.Length; i++)
{
    if (myList[i].Contains(myString)) // (you use the word "contains". either equals or indexof might be appropriate)
    {
        return i;
    }
}

Old Fashion Loops sind fast immer die schnellsten.


Schlagen Sie vor, dass diese Methode schneller (also effizienter) ist, da ich mich für Effizienz entscheide?
Dimitris Iliadis

2
Ich habe es nicht perfekt getestet, aber ich würde vermuten, dass dies schneller sein würde. Es ist immer nur ein Durchlauf durch die Liste erforderlich, bis sie etwas findet und früh ausbricht (wie es die Linq-Optionen tun könnten, wenn sie gut geschrieben sind), ohne den Methodenaufruf-Overhead von linq oder den Lambda-Overhead von linq. Nicht, dass dies Anlass zur Sorge gibt, aber es kann zu Leistungseinbußen kommen.
McKay

Warum nicht List.Equals () verwenden?
F8ER

@ V.7 Weil er nur wissen will, ob ein Element in der Liste einen Teilstring enthält. list.equals ist nicht das richtige Werkzeug für den Job ["abc", "def", "ghi"] enthält "hi", wie es das OP beschreibt. list.equals nimmt nicht einmal die richtigen Datentypen an.
McKay

6

Wenn Sie eine Liste von Zeichenfolgen wünschen, die Ihre Zeichenfolge enthalten:

var newList = myList.Where(x => x.Contains(myString)).ToList();

Eine andere Option ist die Verwendung von Linq FirstOrDefault

var element = myList.Where(x => x.Contains(myString)).FirstOrDefault();

Beachten Sie, dass Containsbei dieser Methode zwischen Groß- und Kleinschreibung unterschieden wird.


1
Gute Erinnerung an Groß- und Kleinschreibung, implementieren Sie StringComparison.InvariantCultureIgnoreCase
JoshYates1980

2

Sie können die FirstOrDefaultErweiterungsmethode von Linq verwenden:

string element = myList.FirstOrDefault(s => s.Contains(myString));

Dies gibt das erste Element zurück, das den Teilstring enthält myString, oder nullwenn kein solches Element gefunden wird.

Wenn Sie nur den Index benötigen, verwenden Sie die Methode der List<T>Klasse FindIndex:

int index = myList.FindIndex(s => s.Contains(myString));

Dies gibt den Index des ersten Elements zurück, das den Teilstring enthält myString, oder -1wenn kein solches Element gefunden wird.


2

Viele gute Antworten hier, aber ich benutze eine einfache mit Exists , wie unten:

foreach (var setting in FullList)
{
    if(cleanList.Exists(x => x.ProcedureName == setting.ProcedureName)) 
       setting.IsActive = true; // do you business logic here 
    else
       setting.IsActive = false;
    updateList.Add(setting);
}

2

Sie sollten in der Lage sein, so etwas zu verwenden, es hat für mich in Ordnung funktioniert:

var valuesToMatch = yourList.Where(stringCheck => stringCheck.Contains(myString));

oder so ähnlich, wenn Sie schauen müssen, wo es nicht passt.

 var valuesToMatch = yourList.Where(stringCheck => !stringCheck.Contains(myString));

1

Sie können verwenden

var match=myList.Where(item=>item.Contains("Required String"));
foreach(var i in match)
{
//do something with the matched items
}

LINQ bietet Ihnen die Möglichkeit, jede Datensammlung abzufragen. Sie können die Syntax wie eine Datenbankabfrage (select, where usw.) für eine Sammlung (hier die Sammlung (Liste) von Zeichenfolgen) verwenden.

Sie tun also wie "Hol mir Gegenstände von der Liste, wo sie eine bestimmte Bedingung erfüllen".

innerhalb der Wo Sie einen "Lambda-Ausdruck" verwenden

kurz zu sagen, Lambda-Ausdruck ist so etwas wie (Eingabeparameter => Rückgabewert)

Für einen Parameter "item" wird "item.Contains (" erforderliche Zeichenfolge ")" zurückgegeben. Es gibt also true zurück, wenn das Element die Zeichenfolge enthält, und wird dadurch aus der Liste ausgewählt, da es die Bedingung erfüllt.


1

Um es einfach zu halten, verwenden Sie dies;

foreach(string item in myList)//Iterate through each item.
{
 if(item.Contains("Search Term")//True if the item contains search pattern.
 {
   return item;//Return the matched item.
 }
}

Alternativ können Sie dies auch mit der for-Schleife verwenden.

    for (int iterator = 0; iterator < myList.Count; iterator++)
    {
        if (myList[iterator].Contains("String Pattern"))
        {
            return myList[iterator];
        }
    }

Um nur darauf hinzuweisen, Sie haben eine Endklammer in einer der Codezeilen verpasst. If (item.Contains ("Search Term"))
Alex

0

Ich habe die Bool-Option in anderen Antworten nicht gesehen, daher hoffe ich, dass der folgende Code jemandem hilft.

Benutz einfach Any()

string myString = "test";
bool exists = myList
             .Where(w => w.COLUMN_TO_CHECK.Contains(myString)).Any();

0

Es ist möglich, Any, Where, First und FirstOrDefault zu kombinieren. oder platzieren Sie das Prädikat einfach in eine dieser Methoden, je nachdem, was benötigt wird.

Sie sollten First wahrscheinlich vermeiden, es sei denn, Sie möchten eine Ausnahme auslösen, wenn keine Übereinstimmung gefunden wird. FirstOrDefault ist normalerweise die bessere Option, solange Sie wissen, dass der Standardwert des Typs zurückgegeben wird, wenn keine Übereinstimmung gefunden wird (der Standardwert der Zeichenfolge ist null, int ist 0, bool ist false usw.).

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


bool exists;
string firstMatch;
IEnumerable<string> matchingList;

var myList = new List<string>() { "foo", "bar", "foobar" };

exists = myList.Any(x => x.Contains("o"));
// exists => true

firstMatch = myList.FirstOrDefault(x => x.Contains("o"));
firstMatch = myList.First(x => x.Contains("o"));
// firstMatch => "foo"

firstMatch = myList.First(x => x.Contains("dark side"));
// throws exception because no element contains "dark side"

firstMatch = myList.FirstOrDefault(x => x.Contains("dark side"));
// firstMatch => null

matchingList = myList.Where(x => x.Contains("o")); 
// matchingList => { "foo", "foobar" }

Testen Sie diesen Code unter https://rextester.com/TXDL57489

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.