删除字符串中的所有索引

本文关键字:索引 字符串 删除 | 更新日期: 2023-09-27 17:56:39

我有 int ( Dictionary<int, int> ) 的字典,它有一个字符串中所有括号的索引(键是openStartParenthesisIndex,值是closeEndParenthesisIndex

例如在文本中

stringX.stringY(())() -> stringX.stringY$($()^)^$()^
$ = openParenthesisStartIndex
^ = closeParenthesisEndIndex

字典条目:

             key                            value
          (openParenthesisStartIndex) --- (closeParenthesisEndIndex)
    item1    15                            19
    item2    16                            18
    item3    19                            21

我的问题是当我循环我的字典并尝试在字符串上删除它时,下一个循环索引无效,因为它已经更改,因为我删除了它.

string myText = "stringX.stringY(())()";
Dictionary<int, int> myIndexs = new Dictionary<int, int>();
foreach (var x in myIndexs)
{
    myText = myText.Remove(item.Key, 1).Remove(item.Value-1);
}

问题:如何删除字符串中的所有索引(从 startIndex[key] 到 endIndex[value])?

删除字符串中的所有索引

为了防止索引更改,一个技巧是从末尾开始删除出现次数:

string myText = stringX.stringY(())();
Dictionary<int, int> myIndexs = new Dictionary<int, int>();
var allIndexes = myIndexs.Keys.Concat(myIndexs.Values);
foreach (var index in allIndexes.OrderByDescending(i => i))
{
    myText = myText.Remove(index, 1);
}

请注意,您可能根本不需要字典。考虑将其替换为列表。

StringBuilder将更适合您的情况,因为您不断更改数据。StringBuilder MSDN

按降序对键进行排序也适用于删除所有索引。

另一种解决方法是将中间字符放在所需的索引处,并在最后替换该字符的所有实例。

StringBuilder ab = new StringBuilder("ab(cd)");
ab.Remove(2, 1);
ab.Insert(2, "`");
ab.Remove(5, 1);
ab.Insert(5, "`");
ab.Replace("`", "");
System.Console.Write(ab);

字符串 当您对字符串进行更改时,总是会创建一个新字符串,因此您想要的是创建一个没有删除部分的新字符串。由于处理潜在重叠的方式,此代码有点复杂。也许更好的方法是清理索引,以正确的顺序列出表示相同删除的索引,而不会重叠。

public static string removeAtIndexes(string source)
{
    var indexes = new Tuple<int, int>[]
    {
        new Tuple<int, int>(15, 19),
        new Tuple<int, int>(16, 18),
        new Tuple<int, int>(19, 21)
    };
    var sb = new StringBuilder();
    var last = 0;
    bool copying = true;
    for (var i = 0; i < source.Length; i++)
    {
        var end = false;
        foreach (var index in indexes)
        {
            if (copying)
            {
                if (index.Item1 <= i)
                {
                    copying = false;
                    break;
                }
            }
            else
            {
                if (index.Item2 < i)
                {
                    end = true;
                }
            }
        }
        if (false == copying && end)
        {
            copying = true;
        }
        if(copying)
        {
            sb.Append(source[i]);
        }
    }
    return sb.ToString();
}