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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 03:47:36  来源:igfitidea点击:

Removing characters from strings with LINQ

c#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);