如何比较和更新数组重叠中的第一个引用



假设我有以下2个数组。。。

string[] A = ["word1", "word2", "word3"];
string[] B = ["word0", "word1", "word2", "word3", "word4", "word5", "word6", "word1", "word2", "word3"];

如果我想将A与B进行比较,并删除B中的第一个出现,那么它看起来是这样的。。。

string[] B = ["word0", " ", " ", " ", "word4", "word5", "word6", "word1", "word2", "word3"];

我该怎么做?

一个简单的方法是使用Array.IndexOfB:中查找来自A的每个单词的第一个出现

foreach (var word in A)
{
    var index = Array.IndexOf(B, word);
    if (index >= 0) {
        B[index] = " "; // or whatever other value
    }
}

请注意,如果替换值本身存在于A中,则这可能无法按预期工作——如果可能的话,您应该指定希望发生的情况。

更新:看起来您想在B中查找并替换子序列A作为一个整体,而不是单个元素。这是一个非常不同的问题。一个(幼稚的)实现是:

var start = Enumerable.Range(0, B.Length - A.Length + 1)
                      .Where(i => B.Skip(i).Take(A.Length).SequenceEqual(A))
                      .DefaultIfEmpty(-1)
                      .First();
if (start != -1)
{
    for (var i = 0; i < A.Length; ++i)
    {
        B[start + i] = " ";
    }
}

我完全支持@Jon给出的答案。它相当快速、简洁和精确。尽管如此,我还是有一个完全不同的方法,一个更实用的方法,以防万一到了string[],你实际上想说一些更流畅的东西:

假设你有一个可能无限的字符串序列,而不是B的原始数组。它可以是任何东西:直接从数据库中读取实体,一个一元字符串生成器,任何东西:

string[] A = ["word1", "word2", "word3"];
IEnumerable[] B = ...;

你可以给自己写一个很好的小扩展方法:

public static class MyHelpers {
    public static IEnumerable<string> ReplaceFirstOccurrencesWithEmpty(this IEnumerable<string> @this, IEnumerable<string> a) {
        // prepare a HashSet<string> to know how many A elements there still exist
        var set = new Hashset<string>(a);
        // iterate and apply the rule you asked about
        // virtually forever (if needed)
        foreach (var value in @this) {
            if (set.Remove(value))
                yield return "";
            else
                yield return value;
        }
    }
}

然后你可以这样使用它,即使是在你最初的A和B阵列上:

string[] A = ["word1", "word2", "word3"];
string[] B = ["word0", "word1", "word2", "word3", "word4", "word5", "word6", "word1", "word2", "word3"];
var cQuery = B.ReplaceFirstOccurrencesWithEmpty(A);
string[] c = cQuery.ToArray();

使用LINQ

string[] A = new string[] { "word1", "word2", "word3" };
string[] B = new string[] { "word0", "word1", "word2", "word3", "word4", "word5", "word6", "word1", "word2", "word3" };
string[] result = B.Select((word, i) => i <= A.Length && i > 0 && A[i-1] == word ? "" : word).ToArray();

最新更新