【问题标题】:How to remove an element from a split String?如何从拆分字符串中删除元素?
【发布时间】:2018-02-16 20:08:34
【问题描述】:

我正在尝试从拆分字符串中删除元素/项目/条目。

假设我得到了string [string_] 如下:

string string_ = "one;two;three;four;five;six";

然后我拆分这个 string 得到每个,比如说,item

string[] item = (string_.Split(";"));

除了变量,我没有其他信息。根据用户的选择,我可以获得一个项目 valueindex

假设对于这个例子,用户选择了“four”,即索引“3 ”。

如何使我的字符串看起来像索引 3 已被删除,因为 string_ 将等于以下内容:

"一;二;三;五;六"

我尝试了多种方法,似乎唯一的解决方案是通过 char 方法。

这是真的还是我错过了什么?


编辑建议的 already_posted_answer : 根据用户的选择,与我的 ITEM 不同的问题可能会放在拆分字符串中的任何位置。

【问题讨论】:

标签: c# string split


【解决方案1】:

首先你需要写出更好的变量名,string_ 是一个可怕的名字。甚至像“输入”这样的东西也更好。

string input = "one;two;three;four;five;six";

接下来,您使用Split() 走在正确的轨道上。这将返回一个string 的数组:

string[] splitInput = input.Split(";");

生成的字符串数组将如下所示:

//string[0] = one
//string[1] = two
//string[2] = three
//string[3] = four
//string[4] = five
//string[5] = six

使用已知索引删除

如果您想从数组中删除特定元素,您可以使用 ToList() 将 Split() 的结果设为 List<T>,并使用生成的 RemoveAt() 方法List<T>

List<string> splitList = input.Split(';').ToList();
splitList.RemoveAt(3);

//Re-create the string
string outputString = string.Join(";", splitList);
//output is: "one;two;three;five;six"

删除所有匹配输入的字符串

如果您需要在不知道其索引但知道实际字符串的情况下从列表中删除项目,您可以使用 LINQ 的 Where() 过滤掉匹配的项目:

//Get the input from the user somehow
string userInput = Console.ReadLine();
IEnumerable<string> filteredList = input.Split(';')
                                      .Where(x => string.Compare(x, userInput, true) != 0);

//Re-create the string
string outputString = string.Join(";", filteredList);

我做了一个小提琴来演示这两种方法here

【讨论】:

  • 你太棒了。现在我意识到我正在使用字符串或 int 进行测试,但我完全忘记了那个中性的“var”。非常感谢。
  • 鉴于“ToList()”调用,这不是内存方面的最佳选择。
  • @YurySchkatula 抢先优化是个坏主意。 ToList 需要使用RemoveAt()
  • @Yury 如果您担心从 CPU 中挤出性能,那您就完全错了。试试 Rust 或 C
  • @Mightee,C# 给了你一个更大的锤子。因此,与滥用 Rust 或 C 相比,滥用它会造成更多的性能损失。尽管您在 C# 中有 GC,但您必须了解它是如何工作的,而不是严重干扰它。真的。
【解决方案2】:

您可以通过以下方式将字符串数组转换为列表:

var list = new List<string>(item);

创建列表后,您可以轻松删除元素:

var index = list.IndexOf("four");
list.RemoveAt(index);

加入字符串:

var result = String.Join(";", list.ToArray());

结果:

【讨论】:

  • 不需要.IndexOf("four")list.Remove("four") 为你做这件事。
  • @NamelessLambda 感谢指出,.Remove()也可以使用。
【解决方案3】:

您可以将您的字符串数组转换为List&lt;string&gt;,并且由于您有要删除的项目的索引,您可以使用RemoveAt 删除该项目,然后将这些项目重新连接成一个字符串。

这是一个完整的控制台应用程序示例:

static void Main(string[] args)
{
    string string_ = "one;two;three;four;five;six";
    string[] items = (string_.Split(';'));

    Console.WriteLine("Please select an item to remove:");
    for (int i = 0;i<items.Length;i++)
    {
        Console.WriteLine(string.Format("{0}- {1}", (i + 1).ToString(), items[i]));
    }
    int num = 0;
    int.TryParse(Console.ReadLine(), out num);
    if (num > 0 && num <= items.Length)
    {
        List<string> itemsList = items.ToList();
        itemsList.RemoveAt(num - 1);
        string newString = string.Join(";", itemsList);
        Console.WriteLine(string.Format("The new string is: {0}", newString));
    }
    else
    {
        Console.WriteLine("Invalid number!");
    }
    Console.ReadLine();
}

希望对您有所帮助。

【讨论】:

    【解决方案4】:

    我们可以使用 LINQ。 最初的计划是拆分字符串,然后创建两个可枚举的并集:项目之前和之后。像这样的:

        // preconditions
        const int idx = 3;
        string string_ = "one;two;three;four;five;six";
    
        // actual transformation
        string[] item = (string_.Split(';'));
        var iterator = item.Take(idx).Concat(item.Skip(idx + 1));
    
        // output the results
        var result = string.Join(";", iterator);
        Console.Write(result);
    

    【讨论】:

    • 这也很有效。谢谢你的帮助。想解释一下您的解决方案如何更适合内存?我是内存优化的新手,maccettura 的解决方案(在我的水平上)更容易理解。
    • 如果列表中有重复项,则此解决方案不正确。为什么是“union”而不是“concat”?
    • 另外,您不必要地重复序列两次。编写自己的辅助函数会更好:public static IEnumerable&lt;T&gt; SkipOver&lt;T&gt;(this IEnumerable&lt;T&gt; items, int index) =&gt; items.Where((dummy, i) =&gt; i != index) 然后只说string.Join(";", items.SkipOver(index)) 现在您(1)只迭代序列一次,并且(2)您已经构建了一个可能更普遍的辅助方法有用,这是自我描述的。
    • @EricLippert,哦!你说得对,我忘记了 Union() 的独特性质。打算修改我的答案。
    • @Bo.Ga.,该解决方案创建了太多临时实例,这些实例可能无济于事。想象一下,您参观了一家杂货店,然后带着满满一车的食物回家,然后把除了小蛋糕以外的所有东西都扔到垃圾桶里。
    【解决方案5】:

    这对你有用吗?

    如果你像这样创建一个新字符串,那么将 string_ 的值替换为新字符串的值。

    string string_ = "one;two;three;four;five;six";
    string newstring = string_.Replace("four", "");
    string_ = newstring.Replace(";;", ";");
    

    【讨论】:

    • 如果我们有几个“四个”事件并计划只删除其中一个怎么办? (不是第一个,不是最后一个等)
    • 我认为 OP 正在为用户提供选择。我没有多次看到很多菜单有相同的选择。
    • 查看下一个答案,以及 Eric Lippert 关于“二十四”的评论。这是绝对正确的问题。
    猜你喜欢
    • 2021-10-22
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多