¿Está la cadena en una matriz?

107

¿Cuál sería la mejor manera de buscar en un string[]para ver si contiene un elemento? Esta fue mi primera oportunidad. Pero quizás haya algo que estoy pasando por alto. El tamaño de la matriz no superará los 200 elementos.

bool isStringInArray(string[] strArray, string key)
{
    for (int i = 0; i <= strArray.Length - 1; i++)
        if (strArray[i] == key)
            return true;
    return false;
}
Puntilla
fuente

Respuestas:

210

Simplemente use el método Contains () ya incorporado:

using System.Linq;

//...

string[] array = { "foo", "bar" };
if (array.Contains("foo")) {
    //...
}
Dave Markle
fuente
Por alguna razón, cuando busqué por primera vez el método no pude encontrarlo ... gracias.
Brad
4
@Brad: Eso es porque es un método de extensión que proviene de Enumerable.
AnthonyWJones
8
Como una sola línea:(new string[] { "foo", "bar" }).Contains("foo")
Denis V
8
Aún más corto:new[] { "foo", "bar" }.Contains(foo)
Eric Bole-Feysot
25

Sé que esto es antiguo, pero quería que los nuevos lectores supieran que hay un nuevo método para hacer esto usando métodos genéricos y de extensión.

Puede leer la publicación de mi blog para ver más información sobre cómo hacer esto, pero la idea principal es la siguiente:

Al agregar este método de extensión a su código:

public static bool IsIn<T>(this T source, params T[] values)
{
    return values.Contains(source);
}

puede realizar su búsqueda así:

string myStr = "str3"; 
bool found = myStr.IsIn("str1", "str2", "str3", "str4");

Funciona en cualquier tipo (siempre que cree un buen método igual). Cualquier tipo de valor seguro.

Gabriel McAdams
fuente
Tengo algo como esto, var xxx = csvData.Rows[0].ItemArray[0].IsIn(".00", "0.0", ".25", "0.5", ".5", ".50", ".75");lo que quiero hacer es mirar a través de la tabla de datos who en la primera columna para ver si los valores no terminan en ninguna de las siguientes cadenas ... si no lo hacen, entonces quiero devolver una cadena que indique que falta un valor, .00por ejemplo, usando su ejemplo, parece que no puedo hacer que este funcione, es un poco más complicado ya que no quiero devolver un bool Modifiqué su método para devolver una cadena pero aún no funciona ninguna sugerencia
MethodMan
Esto parece mejor planteado como una pregunta en el sitio. Continúe y haga referencia a esta respuesta si es necesario.
Gabriel McAdams
De hecho, pude encontrar una manera increíble de hacer lo que quería hacer. Escribí algo que verificaría si los valores de una cadena dentro de un bucle for para Datatables ItemArray, terminan con cualquiera de los siguientes valores que tenía en mi string public static bool EndWithValue(this string value, IEnumerable<string> values) { return values.Any(item => value.EndsWith(item)); }
MethodMan
12

Simplemente busca la función Array.Exists (o el método de extensión Contiene si está utilizando .NET 3.5, que es un poco más conveniente).

Noldorin
fuente
3
Aquí hay un ejemplo de trabajo para .NET 2.0: if (Array.Exists (arrayToLookThrough, o => o == elementToSearchFor))
Fueled
7

Linq (para s & g):

var test = "This is the string I'm looking for";
var found = strArray.Any(x=>x == test);

o, dependiendo de los requisitos

var found = strArray.Any(
    x=>x.Equals(test, StringComparison.OrdinalIgnoreCase));

fuente
6

¿Está ordenada la matriz? Si es así, puede hacer una búsqueda binaria . Aquí también está la implementación de .NET. Si la matriz está ordenada, una búsqueda binaria mejorará el rendimiento sobre cualquier solución iterativa.

Andrew Hare
fuente
2

Las matrices son, en general, una estructura de datos deficiente para usar si desea preguntar si un objeto en particular está en la colección o no.

Si va a realizar esta búsqueda con frecuencia, puede que valga la pena utilizar Dictionary<string, something>una matriz en lugar de una. Las búsquedas en un diccionario son O (1) (tiempo constante), mientras que la búsqueda en la matriz es O (N) (toma un tiempo proporcional a la longitud de la matriz).

Incluso si la matriz tiene solo 200 elementos como máximo, si realiza muchas de estas búsquedas, es probable que el Diccionario sea más rápido.

Zack Elan
fuente
1
la búsqueda binaria es O (log n); diccionario subtiende a O (1) - pero hay mucha sobrecarga; para tamaño pequeño a mediano, la búsqueda lineal o la búsqueda binaria pueden tener un rendimiento superior.
Marc Gravell
1

También puede usar LINQ para iterar sobre la matriz. o puede utilizar el método Find, que necesita un delegado para buscarlo. Sin embargo, creo que el método de búsqueda es un poco más caro que simplemente recorrerlo.

masfenix
fuente
El método Find será algorítmicamente idéntico al método de "bucle". Cualquier gasto adicional será la creación de un objeto y tal vez una capa o dos de direccionamiento indirecto pero, si te preocupa optimizarlos a expensas de la legibilidad, te preocupas por las cosas incorrectas.
AwesomeTown
1

Como se mencionó muchas veces en el hilo anterior, depende del marco en uso. .Net Framework 3 y superior tiene los métodos .Contains () o Exists () para matrices. Para otros marcos a continuación, puede hacer el siguiente truco en lugar de recorrer la matriz ...

((IList<string>)"Your String Array Here").Contains("Your Search String Here")

No estoy muy seguro de la eficiencia ... Dave

Dave
fuente
0

Esto es más rápido que iterar a través de la matriz manualmente:

static bool isStringInArray(string[] strArray, string key)
    {

        if (strArray.Contains(key))
            return true;
        return false;
    }
Chris Ballance
fuente
usar LINQ es más rápido que iterar a través de la cadena como se hizo en el ejemplo. strArray.Contains (key) es todo lo que realmente se necesita
Chris Ballance
3
Detrás de escena, strArray.Contains (key) simplemente va a recorrer la matriz de todos modos ... no hay magia involucrada que lo deje de hacer una búsqueda O (n).
AwesomeTown