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.
但那很难看。 Ergo 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语句。
4 个解决方案
#1
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 select keyword, it's obligatory in second form. The documentation says 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语法糖。
#2
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
更新以更正它从源中删除重复项
#3
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更具可读性。
#4
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 new String 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);
#1
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 select keyword, it's obligatory in second form. The documentation says 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语法糖。
#2
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
更新以更正它从源中删除重复项
#3
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更具可读性。
#4
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 new String 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);