Überprüfen Sie, ob sich ein Wert in einem Array befindet (C #).


109

Wie überprüfe ich, ob sich ein Wert in einem Array in C # befindet?

Ich möchte ein Array mit einer Liste von Druckernamen erstellen.

Diese werden einer Methode zugeführt, die nacheinander jede Zeichenfolge betrachtet. Wenn die Zeichenfolge mit einem Wert in einem Array identisch ist, führen Sie diese Aktion aus.

Beispielsweise:

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
foreach (p in printer)
{
   PrinterSetup(p);     
}

Dies sind die Namen der Drucker, die der PrinterSetup-Methode zugeführt werden.

PrinterSetup sieht ungefähr so ​​aus (ein Pseudocode):

public void PrinterSetup(printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

Wie formatiere ich if (printer == "jupiter")so, dass C # es erkennen kann?


4
Versuchen Sie, Ihrem Parameternamen einen Typ (String) zu geben, und es wird in Ordnung sein.
Jon Skeet

2
Ich bin irgendwie verwirrt wie die Frage. Fragen Sie, wie Sie überprüfen können, ob sich ein Wert in einem Array befindet, oder wie Sie einen Zeichenfolgenvergleich in C # durchführen? Wenn es das letztere ist, würden Sie verwenden printer.Equals("jupiter"). Wenn es das erstere ist, verwenden Sie linqundprinter.Contains("jupiter")
newfurniturey

@newfurniturey Ganz so ... die Frage ist verwirrt, der Beispielcode stimmt nicht mit dem Titel überein, und daher sind die Antworten ebenfalls verwirrt; Warum so ein Mist hochgestuft wird, ist mir ein Rätsel. Und es besteht keine Notwendigkeit printer.Equals("jupiter")... Der OP-Code if (printer == "jupiter")funktioniert einwandfrei ... solange er als printerZeichenfolge deklariert ist, wie Skeet bemerkt.
Jim Balter

Antworten:


231

Fügen Sie den erforderlichen Namespace hinzu

using System.Linq;

Dann können Sie die linq- Contains()Methode verwenden

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
if(printer.Contains("jupiter"))
{
    Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
}

2
@ 0A0D. Diese Antwort ist meiner Meinung nach die beste als einfachste / kürzeste und bekannte Methode, um dasselbe zu erreichen ( How do I check if a value is in an array in C#?) und auch effizient. Keine Schleife, keine zusätzliche Methode. Nur ein Namespace ist extra, was keine große Sache ist.
Sami

6
@Sami: Linq verwendet intern Schleifen.

2
@ 0A0D Sam bezieht sich wahrscheinlich auf geschriebenen Code, nicht auf kompilierte Anweisungen. Linq verwendet intern Schleifen und Methoden, aber aus der Sicht der Programmierer ist alles verborgen, was nicht verborgen sein muss.
Trisped

1
Richtig @ 0A0D. Ich meinte, Codierer / Entwickler brauchten keine rechte Schleife. Natürlich braucht die Überprüfung vom Array eine Schleife :)
Sami

3
Dies ist sicherlich einfach und empfehlenswert. Wenn Sie keinen Zugriff auf Linq haben oder Linq nicht verwenden möchten, können Sie sich auf eine explizite Schnittstellenimplementierung des Arrays verlassen. Seit .NET 1.1 haben wir das, ((IList)printer).Contains("Jupiter")was nicht generisch ist (möglicherweise Werttypen usw.) und sogar für mehrdimensionale Arrays funktioniert. Und seit .NET 2.0 haben wir das Magischere, ((IList<string>)printer).Contains("Jupiter")das typsicherer ist. Der Linq-Ansatz war in .NET 3.5 neu.
Jeppe Stig Nielsen

29
   string[] array = { "cat", "dot", "perls" };

// Use Array.Exists in different ways.
bool a = Array.Exists(array, element => element == "perls");
bool b = Array.Exists(array, element => element == "python");
bool c = Array.Exists(array, element => element.StartsWith("d"));
bool d = Array.Exists(array, element => element.StartsWith("x"));

// Display bools.
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
----------------------------output-----------------------------------

1) Richtig 2) Falsch 3) Richtig 4) Falsch


6
Dies sollte die akzeptierte Antwort sein. Wenn Sie ein Array verwenden, ist es nicht völlig unwahrscheinlich, dass die Leistung eine Rolle spielt. In diesem Fall ist Linq oft die falsche Wahl.
Philm

22
if ((new [] {"foo", "bar", "baaz"}).Contains("bar"))
{

}  

Dies ist ein allgemeines Beispiel - können Sie eines bereitstellen, das der Frage besser entspricht?
Kaz

9
Es mag ein allgemeines Beispiel sein, aber es ist genau das, wonach ich gesucht habe.
Grant Birchmeier

7

Etwas wie das?

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
PrinterSetup(printer);

// redefine PrinterSetup this way:
public void PrinterSetup(string[] printer)
{
    foreach (p in printer.Where(c => c == "jupiter"))
    {
        Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
    }
}

7
    public static bool Contains(Array a, object val)
    {
        return Array.IndexOf(a, val) != -1;
    }

2
Ich mag das. Es schlägt jedoch fehl, wenn aes sich um ein mehrdimensionales Array handelt (wie new string[10, 20, 15]zum Beispiel), mit einer Ausnahme. Es wird auch mit eindimensionalen Arrays fehlschlagen, die nicht von Null indiziert sind (wie Array.CreateInstance(typeof(string), new[] { 5, }, new[] { -2, })ich es zugegebenermaßen selten in C # gebe), mit einem möglicherweise falschen Rückgabewert. Diese Mängel sind mit Generika leicht zu beheben:public static bool Contains<TElement>(TElement[] a, TElement val) { return Array.IndexOf(a, val) != -1; }
Jeppe Stig Nielsen

Ich mag das, aber nur, weil es ohne Linq ist und bestätigt, dass IndexOf das einzige ist, was noch verwendet werden kann.
Bitterblue

6

Hinweis: Die Frage bezieht sich auf Arrays von Zeichenfolgen. Die genannten Routinen dürfen nicht mit der .Contains-Methode für einzelne Zeichenfolgen gemischt werden.

Ich möchte eine erweiterte Antwort hinzufügen, die sich auf verschiedene C # -Versionen bezieht, und zwar aus zwei Gründen:

  • Die akzeptierte Antwort erfordert Linq, das perfekt idiomatisches C # ist, obwohl es nicht kostenlos ist und in C # 2.0 oder niedriger nicht verfügbar ist. Wenn ein Array beteiligt ist, kann die Leistung von Bedeutung sein. Daher gibt es Situationen, in denen Sie bei Array-Methoden bleiben möchten.

  • Keine Antwort befasst sich direkt mit der Frage, wo sie auch gebeten wurde, dies in eine Funktion zu setzen (Da einige Antworten auch Strings mit Arrays von Strings mischen, ist dies nicht völlig unwichtig).

Array.Exists () ist eine C # /. NET 2.0-Methode und benötigt keine Linq. Die Suche in Arrays ist O (n). Verwenden Sie für einen noch schnelleren Zugriff HashSet oder ähnliche Sammlungen.

Seit .NET 3.5 gibt es auch eine generische Methode Array<T>.Exists():

public void PrinterSetup(string[] printer)
{
   if (Array.Exists(printer, x => x == "jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

Sie können eine eigene Erweiterungsmethode (C # 3.0 und höher) schreiben, um den syntaktischen Zucker hinzuzufügen, um die gleichen / ähnlichen ".Contains" wie für Zeichenfolgen für alle Arrays zu erhalten, ohne Linq einzuschließen:

// Using the generic extension method below as requested.
public void PrinterSetup(string[] printer)
{
   if (printer.ArrayContains("jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

public static bool ArrayContains<T>(this T[] thisArray, T searchElement)
{
   // If you want this to find "null" values, you could change the code here
   return Array.Exists<T>(thisArray, x => x.Equals(searchElement));
}

In diesem Fall wird diese ArrayContains()Methode verwendet und nicht die Contains-Methode von Linq.

Die an anderer Stelle erwähnten .Contains-Methoden beziehen sich auf List<T>.Contains(seit C # 2.0) oder ArrayList.Contains(seit C # 1.1), nicht jedoch auf Arrays selbst direkt.


1
Ich schlage vor, den Namen in ArrayContains () zu ändern, um Verwechslungen mit Linq Contains () zu vermeiden
peter.cyc

Ich habe dies getan, obwohl es auch Argumente dagegen gibt: Es ist die Grundidee des Polymorphismus, denselben Namen für verschiedene Datentypen zu verwenden, insbesondere unter Berücksichtigung einer Linq-Einstellung. Die Verwendung unterschiedlicher Namen ist nicht polymorph. Aber Lesbarkeit und die Vermeidung von Missverständnissen werden gewinnen, denke ich, ja.
Philm

4

Sie vermissen nur etwas in Ihrer Methode:

public void PrinterSetup(string printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
   }
}

Fügen stringSie einfach hinzu und es wird Ihnen gut gehen.


3

Nicht ganz klar, was Ihr Problem ist, aber es hört sich so an, als ob Sie so etwas wollen:

    List<string> printer = new List<string>( new [] { "jupiter", "neptune", "pangea", "mercury", "sonic" } );

    if( printer.Exists( p => p.Equals( "jupiter" ) ) )
    {
        ...
    }

2

Erwägen Sie die Verwendung von HashSet<T>Class, um die Suchleistung zu verbessern:

Diese Methode ist eine O (1) -Operation.

- HashSet<T>.ContainsMethode (T), MSDN .

Beispielsweise:

class PrinterInstaller
{
    private static readonly HashSet<string> PrinterNames = new HashSet<string>
        {
            "jupiter", "neptune", "pangea", "mercury", "sonic"
        };

    public void Setup(string printerName)
    {
        if (!PrinterNames.Contains(printerName))
        {
            throw new ArgumentException("Unknown printer name", "printerName");
        }
        // ...
    }
}

1

Ich habe jetzt über 2 Stunden gesucht, um einen guten Weg zu finden , wie man Duplikate in einer Liste findet und wie man sie entfernt . Hier ist die einfachste Antwort:

//Copy the string array with the filtered data of the analytics db into an list
// a list should be easier to use
List<string> list_filtered_data = new List<string>(analytics_db_filtered_data);

// Get distinct elements and convert into a list again.
List<string> distinct = list_filtered_data.Distinct().ToList();

Die Ausgabe sieht folgendermaßen aus: Doppelte Elemente werden in der neuen Liste mit dem Namen "Ausgesprochen" entfernt!

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.