C# 使用 LINQ 从字符串中删除字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/449513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Removing characters from strings with LINQ
提问by core
I'm trying to brush up on my LINQ by writing some simple extension methods. Is there any better way to write such a function as below that removes a given list of characters from a string (using LINQ)?
我正在尝试通过编写一些简单的扩展方法来复习我的 LINQ。有没有更好的方法来编写如下这样的函数来从字符串中删除给定的字符列表(使用 LINQ)?
It helps me to think of the extension methods that LINQ relies on first:
它帮助我想到了 LINQ 首先依赖的扩展方法:
public static string Remove(this string s, IEnumerable<char> chars)
{
string removeChars = string.Concat(chars);
return new string(s.ToCharArray().Where(c => !removeChars.Contains(c)).ToArray());
}
But that's pretty ugly. Ergo LINQ.
但这太丑了。因此,LINQ。
The difference that I notice in the LINQ statement is that I have to use 'select' whereas with the extension method, I don't have to.
我在 LINQ 语句中注意到的不同之处在于我必须使用“select”,而使用扩展方法则不必。
/// <summary>Strip characters out of a string.</summary>
/// <param name="chars">The characters to remove.</param>
public static string Remove(this string s, IEnumerable<char> chars)
{
string removeChars = string.Concat(chars);
var stripped = from c in s.ToCharArray()
where !removeChars.Contains(c)
select c;
return new string(stripped.ToArray());
}
So I'm wondering if this (last snippet above) is the tersest LINQ statement to accomplish removal of characters.
所以我想知道这(上面的最后一个片段)是否是完成字符删除的最简洁的 LINQ 语句。
采纳答案by Alexander Prokofyev
I would prefer the first form with extension methods though simplified to
我更喜欢带有扩展方法的第一种形式,尽管简化为
public static string Remove(this string s, IEnumerable<char> chars)
{
return new string(s.Where(c => !chars.Contains(c)).ToArray());
}
As for selectkeyword, it's obligatory in second form. The documentationsays what "A query expression must terminate with either a select clause or a group clause". That's why I would avoid LINQ syntactic sugar.
至于select关键字,它在第二种形式中是强制性的。该文件说什么“的查询表达式必须以select子句或group子句结束”。这就是为什么我会避免使用 LINQ 语法糖。
回答by JaredPar
try this for terseness
试试这个
public static string Remove(this string source, IEnumerable<char> chars) {
return new String(source.Where(x => !chars.Contains(x)).ToArray());
}
EDIT
编辑
Updated to correct it removing duplicates from source
更新以更正它从源中删除重复项
回答by ccook
Personally I tend to use the first syntax for non relational situations. When I need to perform relational operations (join), say with Expression Trees against SQL i use the later. But, this is only because its more readable for me having used SQL for a while.
我个人倾向于在非关系情况下使用第一种语法。当我需要执行关系操作(连接)时,比如说使用针对 SQL 的表达式树,我使用后者。但是,这仅仅是因为它对我使用 SQL 一段时间后更具可读性。
回答by Rolfvm
You get a little performance increase when using a stringBuilder instead of the new string. Below results in:
使用 stringBuilder 而不是新字符串时,性能会有所提高。结果如下:
StringBuilder 00:00:13.9930633 new String 00:00:15.1495309
StringBuilder 00:00:13.9930633 新字符串 00:00:15.1495309
string s = "ababababajjjaazsiajjsoajiojsioajlmmzaaokpdahgffaiojsia";
var sw = new Stopwatch();
sw.Start();
var toRemove = new char[] { 'j', 'a', 'z' };
for (int i = 0; i < 1000000; i++)
{
StringBuilder sb = new StringBuilder(s.Length, s.Length);
foreach (var c in s) if (!toRemove.Contains(c)) sb.Append(c);
}
Console.WriteLine("StringBuilder " + sw.Elapsed);
sw.Restart();
for (int i = 0; i < 1000000; i++)
{
new string(s.Where(c => !toRemove.Contains(c)).ToArray());
}
Console.WriteLine("new String " + sw.Elapsed);