Строка в массиве?

107

Как лучше всего посмотреть, string[]содержит ли он элемент. Это была моя первая попытка. Но, возможно, я кое-что не замечаю. Размер массива не должен превышать 200 элементов.

bool isStringInArray(string[] strArray, string key)
{
    for (int i = 0; i <= strArray.Length - 1; i++)
        if (strArray[i] == key)
            return true;
    return false;
}
Брэд
источник

Ответы:

210

Просто используйте уже встроенный метод Contains ():

using System.Linq;

//...

string[] array = { "foo", "bar" };
if (array.Contains("foo")) {
    //...
}
Дэйв Маркл
источник
По какой-то причине, когда я впервые искал метод, я не мог его найти ... спасибо.
Брэд,
4
@Brad: Это потому, что это метод расширения из Enumerable.
AnthonyWJones, 01
8
В качестве однострочного:(new string[] { "foo", "bar" }).Contains("foo")
Denis V
8
Еще короче:new[] { "foo", "bar" }.Contains(foo)
Эрик Боле-Фейсот 01
25

Я знаю, что это старый, но я хотел, чтобы новые читатели знали, что есть новый метод, позволяющий сделать это, используя универсальные методы и методы расширения.

Вы можете прочитать мое сообщение в блоге, чтобы узнать больше о том, как это сделать, но основная идея такова:

Добавив этот метод расширения в свой код:

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

вы можете выполнить свой поиск следующим образом:

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

Он работает с любым типом (если вы создаете хороший метод равенства). Любой тип значения точно.

Габриэль Макадамс
источник
У меня есть что-то вроде этого, var xxx = csvData.Rows[0].ItemArray[0].IsIn(".00", "0.0", ".25", "0.5", ".5", ".50", ".75");что я хочу сделать, это просмотреть список данных who в первом столбце, чтобы увидеть, не заканчиваются ли значения какой-либо из следующих строк ... если нет, то я хочу вернуть строку, в которой говорится, что в нем отсутствует значение, .00например, используя ваш пример. Я не могу заставить его работать, это немного сложнее, так как я не хочу возвращать bool. Я изменил ваш метод, чтобы вернуть строку, но все еще не работает никаких предложений
MethodMan
Кажется, лучше задать вопрос на сайте. При необходимости обратитесь к этому ответу.
Габриэль Макадамс
На самом деле мне удалось придумать отличный способ делать то, что я хотел. Я написал что-то, что проверяет, заканчиваются ли значения строки внутри цикла for для Datatables ItemArray любым из следующих значений, которые были в моем строка public static bool EndWithValue(this string value, IEnumerable<string> values) { return values.Any(item => value.EndsWith(item)); }
MethodMan
12

Вы просто выбираете функцию Array.Exists (или метод расширения Contains, если вы используете .NET 3.5, что немного удобнее).

Нолдорин
источник
3
Вот рабочий пример для .NET 2.0: if (Array.Exists (arrayToLookThrough, o => o == elementToSearchFor))
Fueled
7

Linq (для s&g):

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

или, в зависимости от требований

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

источник
6

Массив отсортирован? Если да, вы можете выполнить двоичный поиск . Вот и реализация .NET. Если массив отсортирован, то двоичный поиск повысит производительность по сравнению с любым итеративным решением.

Эндрю Хэйр
источник
2

Массивы, как правило, представляют собой плохую структуру данных для использования, если вы хотите спросить, находится ли конкретный объект в коллекции или нет.

Если вы будете часто выполнять этот поиск, возможно, стоит использовать Dictionary<string, something> вместо массива. Поиск в словаре - O (1) (постоянное время), а поиск по массиву - O (N) (время, пропорциональное длине массива).

Даже если в массиве не более 200 элементов, если вы будете выполнять много таких поисков, словарь, вероятно, будет быстрее.

Зак Элан
источник
1
двоичный поиск - O (log n); словарь соответствует O (1) - но накладных расходов много; для малых и средних размеров линейный поиск или двоичный поиск могут превзойти по производительности.
Марк Грейвелл
1

Вы также можете использовать LINQ для перебора массива. или вы можете использовать метод Find, который использует делегата для его поиска. Однако я думаю, что метод поиска немного дороже, чем простой цикл.

Masfenix
источник
Метод Find будет алгоритмически идентичен методу «сквозного». Любые дополнительные расходы будут связаны с созданием некоторого объекта и, возможно, одним или двумя уровнями косвенного обращения, но, если вы беспокоитесь об их оптимизации за счет удобочитаемости, вы беспокоитесь о неправильных вещах.
AwesomeTown, 01
1

Как неоднократно упоминалось в потоке выше, это зависит от используемой структуры. .Net Framework 3 и выше имеет методы .Contains () или Exists () для массивов. Для других фреймворков, представленных ниже, можно выполнить следующий трюк вместо цикла по массиву ...

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

Не уверен в эффективности ... Дэйв

Дэйв
источник
0

Это быстрее, чем перебирать массив вручную:

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

        if (strArray.Contains(key))
            return true;
        return false;
    }
Крис Балланс
источник
использование LINQ быстрее, чем итерация по строке, как это было сделано в примере. strArray.Contains (key) - это все, что действительно необходимо,
Крис Балланс,
3
За кулисами strArray.Contains (key) все равно будет перебирать массив в цикле ... здесь нет магии, которая заставит вас отказаться от поиска O (n).
AwesomeTown,
0

Если вы не хотите или просто не можете использовать Linq, вы также можете использовать статическую Array.Exists(...);функцию:

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

Когда Predicate действительно вернет true, однажды catInside также будет истинным.

матейасу
источник