Verifique si un valor está en una matriz (C #)


109

¿Cómo verifico si un valor está en una matriz en C #?

Quiero crear una matriz con una lista de nombres de impresoras.

Estos se enviarán a un método, que examinará cada cadena a su vez, y si la cadena es igual que un valor en una matriz, realice esa acción.

Por ejemplo:

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

Estos son los nombres de las impresoras, que se alimentan al método PrinterSetup.

PrinterSetup se verá así (un pseudocódigo):

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

¿Cómo puedo formatear if (printer == "jupiter")de una manera que C # pueda reconocer?


4
Intente darle al nombre de su parámetro un tipo (cadena) y estará bien.
Jon Skeet

2
Estoy un poco confundido como la pregunta. ¿Está preguntando cómo verificar si un valor está en una matriz, o cómo hacer una comparación de cadenas en C #? Si es lo último, usaría printer.Equals("jupiter"). Si es el primero, use linqyprinter.Contains("jupiter")
muebles nuevos

@newfurniturey Muy bien ... la pregunta es confusa, el código de ejemplo no coincide con el título y, por lo tanto, las respuestas también son confusas; por qué mierda como esta se vota a favor está más allá de mí. Y no hay necesidad de hacer printer.Equals("jupiter")... El código del OP if (printer == "jupiter")funciona bien ... siempre que printerse declare que es una cadena, como señala Skeet.
Jim Balter

Respuestas:


231

Agregar el espacio de nombres necesario

using System.Linq;

Entonces puedes usar el Contains()método linq

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

2
@ 0A0D. Esta respuesta es, creo que la mejor es la forma más simple / más corta y conocida de lograr lo mismo ( How do I check if a value is in an array in C#?) y también eficiente. Sin bucle, sin método adicional. Solo un espacio de nombres es un extra, lo cual no es gran cosa.
Sami

6
@Sami: Linq usa bucles internamente.

2
@ 0A0D Sam probablemente se esté refiriendo a código escrito, no a instrucciones compiladas. Linq usa bucles y métodos internamente, pero desde el punto de vista de los programadores, todo eso está oculto y no hay por qué preocuparse.
Trisped

1
Derecha @ 0A0D. Me refiero a que el codificador / desarrollador no necesitaba un bucle correcto. Fuera de curso, la verificación de la matriz necesita un bucle :)
Sami

3
Sin duda, esto es fácil y recomendable. Si no tiene acceso a Linq, o no desea utilizar Linq, puede confiar en alguna implementación de interfaz explícita de la matriz. Desde .NET 1.1 tenemos ((IList)printer).Contains("Jupiter")que no es genérico (puede incluir tipos de valores de caja, etc.) y funciona incluso para matrices multidimensionales. Y desde .NET 2.0 tenemos el más mágico ((IList<string>)printer).Contains("Jupiter")que es más seguro para los tipos. El enfoque de Linq era nuevo en .NET 3.5.
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) Verdadero 2) Falso 3) Verdadero 4) Falso


6
Esta debería ser la respuesta aceptada. Si utiliza una matriz, no es del todo improbable que el rendimiento sí importe. En este caso, Linq suele ser la elección equivocada.
Philm

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

}  

Este es un ejemplo general: ¿puede proporcionar uno que coincida mejor con la pregunta?
kaz

9
Puede ser un ejemplo general, pero es exactamente lo que estaba buscando.
Grant Birchmeier

7

¿Algo como esto?

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
Me gusta esto. Sin embargo, fallará si aes una matriz multidimensional (como new string[10, 20, 15]por ejemplo), con una excepción. También fallará con matrices unidimensionales que no están indexadas desde cero (como Array.CreateInstance(typeof(string), new[] { 5, }, new[] { -2, }), raro en C #, lo admito), con un valor de retorno posiblemente incorrecto. Estas deficiencias son fáciles de solucionar con genéricos:public static bool Contains<TElement>(TElement[] a, TElement val) { return Array.IndexOf(a, val) != -1; }
Jeppe Stig Nielsen

Me gusta esto, pero solo porque no tiene Linq y confirma que IndexOf es lo único que queda por usar.
Bitterblue

6

Nota: La pregunta es sobre matrices de cadenas. Las rutinas mencionadas no se deben mezclar con el método .Contains de cadenas individuales.

Me gustaría agregar una respuesta extendida que se refiera a diferentes versiones de C # y por dos razones:

  • La respuesta aceptada requiere Linq, que es C # perfectamente idiomático, mientras que no viene sin costos y no está disponible en C # 2.0 o inferior. Cuando se trata de una matriz, el rendimiento puede ser importante, por lo que hay situaciones en las que desea permanecer con los métodos de matriz.

  • Ninguna respuesta atiende directamente a la pregunta en la que también se pidió que pusiera esto en una función (como algunas respuestas también mezclan cadenas con matrices de cadenas, esto no es completamente insignificante).

Array.Exists () es un método C # / .NET 2.0 y no necesita Linq. La búsqueda en matrices es O (n). Para un acceso aún más rápido, use HashSet o colecciones similares.

Desde .NET 3.5 también existe un método genérico 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");
   }
}

Puede escribir un método de extensión propio (C # 3.0 y superior) para agregar el azúcar sintáctico para obtener el mismo / similar ".Contains" que para las cadenas para todas las matrices sin incluir Linq:

// 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));
}

En este caso ArrayContains()se utiliza este método y no el método Contiene de Linq.

Los métodos .Contains mencionados en otra parte se refieren a List<T>.Contains(desde C # 2.0) o ArrayList.Contains(desde C # 1.1), pero no directamente a las matrices.


1
Sugiero cambiar el nombre a ArrayContains () para evitar confusiones con Linq Contains ()
peter.cyc

He hecho esto, aunque también hay argumentos en contra: La idea básica del polimorfismo es usar el mismo nombre para diferentes tipos de datos, especialmente con un ajuste Linq en mente. Usar nombres diferentes no es polimorfo. Pero la legibilidad y la evitación de malentendidos ganarán, creo, así que sí.
Philm

4

Simplemente te falta algo en tu método:

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

Solo agregue stringy estará bien.


3

No está muy claro cuál es su problema, pero parece que quiere algo como esto:

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

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

2

Considere usar HashSet<T>Class por el bien del rendimiento de búsqueda:

Este método es una operación O (1).

- HashSet<T>.ContainsMétodo (T), MSDN .

Por ejemplo:

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

Busqué ahora durante 2 horas para encontrar una manera agradable de encontrar duplicados en una lista y cómo eliminarlos . Aquí está la respuesta más simple:

//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();

La salida se verá así: ¡Los elementos duplicados se eliminarán en la nueva lista llamada distinta!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.