Вы можете выполнить очень эффективно с использованием регулярных выражений, чтобы соответствовать всем гласным и заменить их пустыми строки:
var strArray = new List<string> { "cello", "guitar", "violin" };
var pattern = @"[aeiou]";
var noVowels = strArray.Select(item =>
Regex.Replace(item, pattern, "", RegexOptions.IgnoreCase));
foreach (var item in noVowels) {
Console.WriteLine(item);
}
Это возвращает результаты, которые вы ищете.
Ваша первоначальная попытка не сработала, потому что она оценивала каждое слово отдельно для каждого уникального гласного, содержащегося в нем.
Update: Я сделал некоторые базовые бенчмаркинга этого решения по сравнению с Mathias' HashSet<char>
based solution (benchmark code here), в том числе как компилировать и Noncompiled версий версии Regex. Я побежал против массива 2582 Lorem-Ipsum слов, итерация 10 миллионов раз против множества (так происходит в ~ 25 миллиардов слов), запустив его в LINQPad, беря среднее из 3-х серий:
Init Each Time Init One Time
avg ms % diff avg ms % diff
Regex 586 +1% 586 -
Regex Compiled 581 - 593 +1%
HashSet 2550 +339% 641 +10%
It оказывается, что если вы только инициализируете HashSet
и шаблон string
один раз, то они имеют очень схожую производительность. Regex
превосходит Hashset
, но только едва (80 мс быстрее, чем 25 миллиардов слов) и Regex Compiled and Noncompiled выполняет почти тождественно. Однако, если вы инициализируете HashSet каждый раз, когда вы запускаете его, он убивает производительность для подхода HashSet.
Вынос - это то, что если вы хотите использовать подход HashSet
, обязательно инициализируйте свой HashSet
только один раз за набор символов, которые вы хотите исключить.
Это не лямбда-выражение, это запрос LINQ. – TypeIA
@OndrejJanacek Это запрос. Он не пытается изменить существующую коллекцию, но создает новую, основанную на значениях из исходной коллекции. Если это было не так, тогда не было бы смысла иметь операцию проецирования типа 'select'. – Dirk