2011-01-12 3 views
4

Я хочу проверить, начинается ли строка с любого символа в списке. Моя текущая реализация в C# выглядит следующим образом:Проверьте, начинается ли строка с любого символа в списке

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
private bool startWithColumn(string toCheck) 
{ 
    for(int i=0; i<columnChars.Length; i++) 
    if (toCheck.StartsWith(columnChars[i]+"")) 
    { 
     return true; 
    } 

    return false; 
} 

Я хотел бы знать, если какое-либо решение лучше?

+0

многочисленные ответы идут, чтобы показать, что есть * обязательно * много способов сделать то же самое в C#. – JYelton

ответ

7

Включите проверку и проверьте, находится ли первый символ в допустимом наборе.

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
private bool startWithColumn(string toCheck) 
{ 
    return toCheck != null 
       && toCheck.Length > 0 
       && columnChars.Any(c => c == toCheck[0]); 
} 
4

Вы можете получить первый символ из строки достаточно легко:

char c = toCheck[0]; 

А затем проверить, является ли это в массиве:

return columnChars.Contains(c); 
0

Я считаю, что это один будет быстрее:

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
private bool startWithColumn(string toCheck) 
{ 
    for(int i=0; i<columnChars.Length; i++) 
    if (toCheck.Length > 0 && toCheck[0] == columnChars[i])) 
    { 
     return true; 
    } 

    return false; 
} 
1
return Regex.IsMatch(toCheck, "^[A-E]"); 

В качестве альтернативы:

return toCheck.Length > 0 && columnChars.Contains(toCheck[0]); 
+1

Плохое регулярное выражение. Часто overkill, часто недостаточно мощный :( – delnan

0
private bool startWithColumn(string toCheck) 
{ 
    return (columnChars.IndexOf(toCheck[0]) >=0); 
} 
0

Очевидный способ будет линейно-поиск массива для первого символа строки:

private bool startWithColumn(string toCheck) 
{ 
    return !string.IsNullOrEmpty(toCheck) 
      && Array.IndexOf(columnChars, toCheck[0]) != -1; 
} 

Если у вас ищу работу, считать с использованием HashSet<char> или аналогичного вместо массива, что должно дать вам постоянный поиск. Вероятно, это стоит того, если массив был намного больше; вам придется так или иначе измерять.

0

Вот что я придумал:

readonly char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
    private bool startWithColumn(string toCheck) 
    { 
     return columnChars.Contains(toCheck.Substring(0, 1).ToCharArray()[0]); 
    } 

Edit

Не вижу возможности для создания меньшего количества конверсий:

3
return columnChars.Any(x => x == toCheck[0]); 
0

Вы можете сделать он использует Contains и ElementAt:

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
String testString = "This is test String"; 
var exists = columnChars.Contains(testString.ElementAt(0)); 
2

Если ваш персонаж «список», безусловно, будет char[], я предполагаю, что вы лучше от с:

return toCheck.IndexOfAny(columnChars) == 0; 

Отказ от ответственности: я не протестированные это. Но этот метод просто сидит там.

0

Я люблю свою так здесь LINQ:

 string str = "A quick brown fox"; 
     char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F' }; 

     var query = from c in str.Substring(0, 1) 
        join c1 in chars on c equals c1 
        select c; 

Это даст вам все символы, в списке, которые соответствуют первому символу строки. Небольшая модификация, и вы даже можете получить индекс символа в списке символов, которые вы ищете, в этом случае индекс 0.

здесь является то, что код:

 string str = "A quick brown fox"; 
     char[] chars = { 'Z', 'X', 'A', 'B', 'C', 'D', 'E', 'F' }; 

     var query = from c in str.Substring(0, 1) 
        join c1 in chars on c equals c1 
        select new { Character = c, Index = chars.ToList().IndexOf(c) }; 

     var found = query.ToArray(); 
+0

Итак, вам нужна небольшая (как мало?) Модификация, чтобы решить эту проблему OP, и в конце концов вы получите ужасное решение с объединениями? Извините, но LINQ не является золотой молоток. Регулярные выражения: P –

+0

@Martinho ah, другой linq hater. Regex, серьезно? Это проще в обслуживании и более читабельна? Я думаю, вы код для команды одного человека. – SRM

+0

@Martinho Это объект linq, а не linq to sql, поэтому объединения не так дороги. Кроме того, с 2005 года SQL-сервер оптимизировал ВСЕ пути выполнения, поэтому ad hoc sql, например, генерация linq, работает так же быстро, как хранимый proc, так что аргумент выходит из окна. Linq используется в много корпоративных приложений по какой-то причине.Хотя я признаю, что chars.ToList, который я использовал в запросе linq, может быть оптимизирован. Я не уверен, что компилятор linq будет оптимизировать его и кэшировать это значение или если он получит вызов каждого прохода . Было бы лучше создать локальный ва и использовать это вместо этого. – SRM

4

мне нужно было что-то подобное, но для строк:

Я хотел бы знать, если моя строка subject началась с любой из этих строк:

var qualent3s = new string[] { "D", "M", "H", "JUK"}; 

LINQ, чтобы сделать это очень просто:

qualent3s.Any(x => subject.StartsWith(x)) 
+0

Вы можете упростить запрос: 'qualent3s.Any (subject.StartsWith)' –

0

В таких случаях я использую метод расширения, как это:

public static bool StartsWithAny(this string Text, IEnumerable<string> Needles) { 
      return Needles.Any(x => Text.StartsWith(x)); 
     } 
Смежные вопросы