Czy ciąg jest w tablicy?

107

Jaki byłby najlepszy sposób spojrzenia na element a, string[]aby sprawdzić, czy zawiera element. To była moja pierwsza próba. Ale może jest coś, co przeoczam. Rozmiar tablicy nie będzie większy niż 200 elementów.

bool isStringInArray(string[] strArray, string key)
{
    for (int i = 0; i <= strArray.Length - 1; i++)
        if (strArray[i] == key)
            return true;
    return false;
}
Ćwiek
źródło

Odpowiedzi:

210

Po prostu użyj już wbudowanej metody Contains ():

using System.Linq;

//...

string[] array = { "foo", "bar" };
if (array.Contains("foo")) {
    //...
}
Dave Markle
źródło
Z jakiegoś powodu, kiedy po raz pierwszy szukałem metody, nie mogłem jej znaleźć ... dzięki.
Brad
4
@Brad: To dlatego, że jest to metoda rozszerzenia pochodząca z Enumerable.
AnthonyWJones
8
Jako jedna linijka:(new string[] { "foo", "bar" }).Contains("foo")
Denis V
8
Jeszcze krócej:new[] { "foo", "bar" }.Contains(foo)
Eric Bole-Feysot
25

Wiem, że to jest stare, ale chciałem, aby nowi czytelnicy wiedzieli, że istnieje nowa metoda, aby to zrobić, używając typów ogólnych i metod rozszerzających.

Możesz przeczytać mój post na blogu, aby zobaczyć więcej informacji o tym, jak to zrobić, ale główna idea jest taka:

Dodając tę ​​metodę rozszerzenia do kodu:

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

możesz przeprowadzić wyszukiwanie w ten sposób:

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

Działa na każdym typie (o ile utworzysz dobrą metodę równości). Na pewno każdy typ wartości.

Gabriel McAdams
źródło
Mam coś takiego, var xxx = csvData.Rows[0].ItemArray[0].IsIn(".00", "0.0", ".25", "0.5", ".5", ".50", ".75");co chcę zrobić, to przejrzeć, kto datatable w pierwszej kolumnie, aby sprawdzić, czy wartości nie kończą się żadnym z następujących ciągów ... jeśli nie, chcę zwrócić ciąg stwierdzający, że brakuje wartości, .00na przykład używając twojego przykładu Wydaje się, że nie mogę uruchomić tego, jest to nieco trudniejsze, ponieważ nie chcę zwracać wartości bool Zmieniłem twoją metodę, aby zwracała ciąg, ale nadal nie działa żadne sugestie
MethodMan
To wydaje się lepiej postawione jako pytanie na stronie. Śmiało i w razie potrzeby odwołaj się do tej odpowiedzi.
Gabriel McAdams,
Właściwie udało mi się wymyślić niesamowity sposób na zrobienie tego, co chciałem. Napisałem coś, co sprawdzałoby, czy wartości ciągu wewnątrz pętli for dla elementu Datatables ItemArray kończą się dowolną z następujących wartości, które miałem w moim string public static bool EndWithValue(this string value, IEnumerable<string> values) { return values.Any(item => value.EndsWith(item)); }
MethodMan
12

Po prostu szukasz funkcji Array.Exists (lub metody rozszerzenia Contains, jeśli używasz .NET 3.5, co jest nieco wygodniejsze).

Noldorin
źródło
3
Oto działający przykład dla .NET 2.0: if (Array.Exists (arrayToLookThrough, o => o == elementToSearchFor))
Fueled
7

Linq (dla s & g's):

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

lub w zależności od wymagań

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

źródło
2

Tablice mają ogólnie kiepską strukturę danych, jeśli chcesz zapytać, czy dany obiekt znajduje się w kolekcji, czy nie.

Jeśli będziesz często przeprowadzać to wyszukiwanie, może warto użyć Dictionary<string, something>zamiast tablicy. Wyszukiwanie w słowniku to O (1) (czas stały), podczas gdy przeszukiwanie tablicy to O (N) (zajmuje czas proporcjonalny do długości tablicy).

Nawet jeśli tablica zawiera maksymalnie 200 pozycji, jeśli wykonasz wiele takich wyszukiwań, słownik prawdopodobnie będzie szybszy.

Zack Elan
źródło
1
wyszukiwanie binarne to O (log n); słownik zastępuje O (1) - ale jest dużo narzutów; w przypadku małych i średnich rozmiarów wyszukiwanie liniowe lub wyszukiwanie binarne może być lepsze.
Marc Gravell
1

Możesz również użyć LINQ do iteracji po tablicy. lub możesz użyć metody Find, która zabiera delegata do wyszukania. Jednak myślę, że metoda znajdowania jest nieco droższa niż zwykła pętla.

masfenix
źródło
Metoda Find będzie algorytmicznie identyczna z metodą „przelotową”. Dodatkowym wydatkiem będzie tworzenie obiektów i może warstwa lub dwie pośrednie, ale jeśli martwisz się o ich optymalizację kosztem czytelności, martwisz się o niewłaściwe rzeczy.
AwesomeTown
1

Jak wielokrotnie wspomniano w powyższym wątku, jest to zależne od używanego frameworka. .Net Framework 3 i nowsze wersje mają metody .Contains () lub Exists () dla tablic. W przypadku innych ram poniżej można wykonać następującą sztuczkę zamiast przechodzić przez pętlę po tablicy ...

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

Nie jestem pewien co do wydajności ... Dave

Dave
źródło
0

Jest to szybsze niż ręczne iterowanie po tablicy:

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

        if (strArray.Contains(key))
            return true;
        return false;
    }
Chris Ballance
źródło
korzystanie z LINQ jest szybsze niż iterowanie przez ciąg, jak zostało to zrobione w przykładzie. strArray.Contains (klucz) to wszystko, co jest naprawdę potrzebne
Chris Ballance
3
Za kulisami, strArray.Contains (klucz) i tak będzie po prostu przechodzić przez tablicę ... nie ma w tym żadnej magii, która powstrzymuje Cię od wyszukiwania O (n).
AwesomeTown
0

Jeśli nie chcesz lub po prostu nie możesz używać Linq, możesz również użyć Array.Exists(...);funkcji statycznej :

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

Kiedy Predicate zwróci wartość true, gdy catInside również będzie prawdziwe.

mateiasu
źródło