我想从字符串数组中删除元音我用foreach循环做了但是现在 想要使用LINQ或Lambda表达式
来执行它我尝试过以下代码LINQ
string[] strArray = new string[] { "cello", "guitar", "violin"};
string[] vowels = new string[] { "a", "e", "i", "o", "u" };
var vNovowels = from vitem in strArray
from vowel in vowels
where vitem.Contains(vowel)
select vitem.Replace(vowel, "");
foreach (var item in vNovowels)
{
Console.WriteLine(item);
}
但我没有得到预期的结果。
我得到的以上查询的输出是: -
cllo
cell
guitr
gutar
gitar
voln
vilin
期望的输出:
cll
gtr
vln
答案 0 :(得分:13)
您可以使用正则表达式匹配所有元音并使用空字符串替换它们,从而非常有效地完成此任务:
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);
}
这将返回您要查找的输出。
您的原始尝试无效,因为它会针对其中包含的每个唯一元音单独评估每个单词。
更新:我对此解决方案进行了一些基本的基准测试,而不是Mathias' HashSet<char>
based solution(benchmark code here),包括Regex版本的编译和非编译版本。我用2582个lorem-ipsum单词运行它,对着集合迭代1000万次(所以大约250亿字),在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%
事实证明,如果您只初始化HashSet
和模式string
一次,那么它们的性能非常相似。 Regex
击败了Hashset
,但只有勉强(超过250亿字的速度提高了80毫秒),而且正则表达式编译和非编译的表现几乎相同。但是,如果每次运行它都初始化HashSet,那么它会杀死HashSet方法的性能。
需要注意的是,如果您想使用HashSet
方法,请务必在每组要排除的字符集中初始化HashSet
。
答案 1 :(得分:8)
尽管Yaakov's reg-ex solution在优雅和效率方面要好得多,但为了学习,你可以使用Where
:
string[] strArray = new string[] { "cello", "guitar", "violin" };
var vowels = new HashSet<char>("aeiou"); // or: { 'a', 'e', 'i', 'o', 'u' };
var vNovowels2 = from vitem in strArray
select new string(vitem.Where(c => !vowels.Contains(c)).ToArray());
foreach (var item in vNovowels2)
{
Console.WriteLine(item);
}
答案 2 :(得分:1)
正则表达式替换是执行此操作的最佳方式。
string[] strArray = new string[] { "cello", "guitar", "violin" };
var rx = new Regex("^a|e|i|o|u", RegexOptions.IgnoreCase);
var vNovowels = from vitem in strArray
select rx.Replace(vitem, string.Empty);
foreach (var item in vNovowels)
{
Console.WriteLine(item);
}