Это действительно зависит от того, что вы считаете более читаемым, хотите ли вы использовать символы пунктуации в другом месте и как часто будет вызываться метод.
РЕДАКТИРОВАТЬ: Вот альтернатива методу Рида Копси для определения того, содержит ли строка ровно один из символов.
privatestaticreadonlyHashSet<char>Punctuation=newHashSet<char>("*&#...");publicstaticboolContainsOnePunctuationMark(string text){bool seenOne =false;foreach(char c in text){// TODO: Experiment to see whether HashSet is really faster than// Array.Contains. If all the punctuation is ASCII, there are other// alternatives...if(Punctuation.Contains(c)){if(seenOne){returnfalse;// This is the second punctuation character}
seenOne =true;}}return seenOne;}
Я полагаю, что стоит кэшировать массив char, если производительность является проблемой, но опять же, это может не стоить того, в зависимости от контекста.
Noldorin
1
Да, если вы используете его только в методе, который будет выполняться один раз, оно того не стоит. Однако я думаю, что это улучшает читаемость, а также производительность. ToCharArrayКонечно, при необходимости вы можете использовать встроенную форму.
Джон Скит,
1
@canon: Насколько велик набор? Для очень и очень маленьких наборов я бы ожидал, что Array.Contains будет быстрее. Для больших наборов HashSet может выиграть много миль.
Джон Скит
5
Если вы просто хотите узнать, содержит ли он какой-либо символ, я бы рекомендовал использовать string.IndexOfAny, как предлагается в другом месте.
Если вы хотите убедиться, что строка содержит ровно один из десяти символов и только один, тогда все становится немного сложнее. Я считаю, что самым быстрым способом было бы проверить пересечение, а затем проверить наличие дубликатов.
privatestaticchar[] characters =newchar[]{'*','&',...};publicstaticboolContainsOneCharacter(string text){var intersection = text.Intersect(characters).ToList();if( intersection.Count!=1)returnfalse;// Make sure there is only one character in the text// Get a count of all of the one found characterif(1== text.Count(t => t == intersection[0]))returntrue;returnfalse;}
Да, я полагаю, что в этом случае одиночный цикл, вероятно, будет быстрее, особенно с небольшим набором знаков препинания. Мне было бы любопытно попробовать протестировать это с большими строками, чтобы увидеть, что действительно быстрее.
Рид Копси,
1
Я думаю, что поиск пересечения двух строк в любом случае придется выполнять символ за символом, поэтому я не вижу, как это будет быстрее ... и мой предлагаемый маршрут не только использует один проход, но также имеет вариант «досрочного выхода». Представьте, что текст состоит из миллиона символов, но первые два содержат «*» :)
var specialChars =new[]{'\\','/',':','*','<','>','|','#','{','}','%','~','&'};foreach(var specialChar in specialChars.Where(str.Contains)){Console.Write(string.Format("string must not contain {0}", specialChar));}
поскольку я искал хороший способ определить, была ли определенная строка на самом деле ценой или предложением, например «Слишком мало для отображения».
Я знаю, что это старый, но чтобы прояснить, это не особенно хороший способ сопоставления валют ... Если бы кто-то написал "Ke $ ha", это соответствовало бы цене ... Вместо этого обратитесь к одному правильному способу определить валюту,
Ответы:
На мой взгляд, самый простой способ:
Или в более удобной для чтения форме:
В зависимости от требуемого контекста и производительности вы можете или не захотите кэшировать массив char.
источник
Как говорили другие, используйте IndexOfAny. Однако я бы использовал его так:
Таким образом, вы не создадите новый массив при каждом вызове. Строку также легче сканировать, чем серию символьных литералов, IMO.
Конечно, если вы собираетесь использовать это только один раз, чтобы потраченное впустую создание не было проблемой, вы можете использовать:
или
Это действительно зависит от того, что вы считаете более читаемым, хотите ли вы использовать символы пунктуации в другом месте и как часто будет вызываться метод.
РЕДАКТИРОВАТЬ: Вот альтернатива методу Рида Копси для определения того, содержит ли строка ровно один из символов.
источник
ToCharArray
Конечно, при необходимости вы можете использовать встроенную форму.Если вы просто хотите узнать, содержит ли он какой-либо символ, я бы рекомендовал использовать string.IndexOfAny, как предлагается в другом месте.
Если вы хотите убедиться, что строка содержит ровно один из десяти символов и только один, тогда все становится немного сложнее. Я считаю, что самым быстрым способом было бы проверить пересечение, а затем проверить наличие дубликатов.
источник
Вот документация Microsoft .
источник
источник
Всем спасибо! (И в основном Джон!): Это позволило мне написать следующее:
поскольку я искал хороший способ определить, была ли определенная строка на самом деле ценой или предложением, например «Слишком мало для отображения».
источник