A string está na matriz?

107

Qual seria a melhor maneira de olhar em um string[]para ver se ele contém um elemento. Essa foi minha primeira chance. Mas talvez haja algo que estou esquecendo. O tamanho da matriz não será maior que 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;
}
Brad
fonte

Respostas:

210

Basta usar o método Contains () já integrado:

using System.Linq;

//...

string[] array = { "foo", "bar" };
if (array.Contains("foo")) {
    //...
}
Dave Markle
fonte
Por alguma razão, quando procurei o método pela primeira vez, não consegui encontrar ... obrigado.
Brad
4
@Brad: Isso porque é um método de extensão vindo de Enumerable.
AnthonyWJones
8
Como um one-liner:(new string[] { "foo", "bar" }).Contains("foo")
Denis V
8
Ainda mais curto:new[] { "foo", "bar" }.Contains(foo)
Eric Bole-Feysot
25

Eu sei que isso é antigo, mas eu queria que os novos leitores soubessem que existe um novo método para fazer isso usando métodos genéricos e de extensão.

Você pode ler a postagem do meu blog para ver mais informações sobre como fazer isso, mas a ideia principal é esta:

Adicionando este método de extensão ao seu código:

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

você pode realizar sua pesquisa assim:

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

Funciona em qualquer tipo (contanto que você crie um bom método de igualdade). Qualquer tipo de valor com certeza.

Gabriel McAdams
fonte
Eu tenho algo parecido com isso, o var xxx = csvData.Rows[0].ItemArray[0].IsIn(".00", "0.0", ".25", "0.5", ".5", ".50", ".75");que eu quero fazer é olhar através da tabela de dados who na primeira coluna para ver se os valores não terminam em nenhuma das seguintes strings .. se não terminarem, então eu quero retornar uma string informando que está faltando um valor, .00por exemplo, usando seu exemplo, não consigo fazer este funcionar, é um pouco mais complicado, pois não quero retornar um bool Eu alterei seu método para retornar uma string, mas ainda não funciona nenhuma sugestão
MethodMan
Isso parece melhor colocado como uma pergunta no site. Vá em frente e consulte esta resposta, se necessário.
Gabriel McAdams
Na verdade, consegui descobrir uma maneira incrível de fazer o que queria. Escrevi algo que verificaria se os valores de uma string dentro de um loop for para Datatables ItemArray terminam com qualquer um dos seguintes valores que tive em meu string public static bool EndWithValue(this string value, IEnumerable<string> values) { return values.Any(item => value.EndsWith(item)); }
MethodMan
12

Você está simplesmente atrás da função Array.Exists (ou do método de extensão Contains se estiver usando .NET 3.5, que é um pouco mais conveniente).

Noldorin
fonte
3
Aqui está um exemplo funcional para .NET 2.0: if (Array.Exists (arrayToLookThrough, o => o == elementToSearchFor))
Abastecido em
7

Linq (para s & g's):

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

ou, dependendo dos requisitos

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

fonte
2

Os arrays são, em geral, uma estrutura de dados pobre para usar se você deseja perguntar se um objeto específico está na coleção ou não.

Se você estiver executando essa pesquisa com frequência, pode valer a pena usar um em Dictionary<string, something>vez de um array. As pesquisas em um dicionário são O (1) (tempo constante), enquanto a pesquisa na matriz é O (N) (leva o tempo proporcional ao comprimento da matriz).

Mesmo que a matriz tenha apenas 200 itens no máximo, se você fizer muitas dessas pesquisas, o Dicionário provavelmente será mais rápido.

Zack Elan
fonte
1
a pesquisa binária é O (log n); dicionário subtende a O (1) - mas há muito overhead; para tamanhos pequenos a médios, a pesquisa linear ou a pesquisa binária podem ter um desempenho superior.
Marc Gravell
1

Você também pode usar o LINQ para iterar na matriz. ou você pode usar o método Find, que leva um delegado para pesquisá-lo. No entanto, acho que o método find é um pouco mais caro do que simplesmente fazer um loop.

masfenix
fonte
O método Find será algoritmicamente idêntico ao método "looping-through". Qualquer despesa extra será alguma criação de objeto e talvez uma camada ou duas de indireção, mas, se você está se preocupando em otimizar isso em detrimento da legibilidade, você está se preocupando com as coisas erradas.
AwesomeTown
1

Conforme mencionado muitas vezes no tópico acima, ele depende da estrutura em uso. .Net Framework 3 e superior tem os métodos .Contains () ou Exists () para matrizes. Para outras estruturas abaixo, pode fazer o seguinte truque, em vez de fazer um loop pela matriz ...

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

Não tenho muita certeza sobre a eficiência ... Dave

Dave
fonte
0

Isso é mais rápido do que iterar manualmente pela matriz:

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

        if (strArray.Contains(key))
            return true;
        return false;
    }
Chris Ballance
fonte
usar o LINQ é mais rápido do que iterar pela string, como foi feito no exemplo. strArray.Contains (key) é tudo o que é realmente necessário
Chris Ballance
3
Nos bastidores, strArray.Contains (key) vai apenas percorrer o array de qualquer maneira ... não há mágica envolvida que o impeça de fazer uma pesquisa O (n).
AwesomeTown 01 de
0

Se você não quiser ou simplesmente não puder usar o Linq, você também pode usar a Array.Exists(...);função estática :

https://msdn.microsoft.com/en-us/library/yw84x8be%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

var arr = new string[]{"bird","foo","cat","dog"};

var catInside = Array.Exists( 
  arr, // your Array
  (s)=>{ return s == "cat"; } // the Predicate
);

Quando o Predicado retornar verdadeiro uma vez que catInside, também será verdadeiro.

mateiasu
fonte