从String Array中删除List中的内容

Kov*_*ovu 5 c# arrays list

我有一个String Array x和一个List y,我想从List X中删除Y中的所有数据,如何以最快的方式做到这一点?

例如:X:1)"aaa.bbb.ccc"2)"ddd.eee.fff"3)"ggg.hhh.jjj"

Y:1)"bbb"2)"fff"

结果应该是一个新的列表,其中只有3)存在,因为X.1被Y.1删除而X.2被Y.2删除

怎么做?

我知道我可以在List X上做一个foreach并检查列表Y中的所有内容,这是最快的方法吗?

Mar*_*ell 9

方便的

var Z = X.Where(x => !x.Split('.').Intersect(Y).Any()).ToList();
Run Code Online (Sandbox Code Playgroud)

这与"最快"不同.可能最快(运行时)的方法是使用令牌搜索,例如:

public static bool ContainsToken(string value, string token, char delimiter = '.')
{
    if (string.IsNullOrEmpty(token)) return false;
    if (string.IsNullOrEmpty(value)) return false;

    int lastIndex = -1, idx, endIndex = value.Length - token.Length, tokenLength = token.Length;
    while ((idx = value.IndexOf(token, lastIndex + 1)) > lastIndex)
    {
        lastIndex = idx;
        if ((idx == 0 || (value[idx - 1] == delimiter))
            && (idx == endIndex || (value[idx + tokenLength] == delimiter)))
        {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

然后像:

var list = new List<string>(X.Length);
foreach(var x in X)
{
    bool found = false;
    foreach(var y in Y)
    {
        if(ContainsToken(x, y, '.'))
        {
            found = true;
            break;
        }
    }
    if (!found) list.Add(x);
}
Run Code Online (Sandbox Code Playgroud)

这个:

  • (为的输出不分配阵列Split为,的params char[]Split)
  • 不会创建任何新string实例(用于输出Split)
  • 不使用委托抽象
  • 没有捕获范围
  • 使用struct自定义迭代器List<T>而不是class迭代器IEnumerable<T>
  • List<T>适当的最坏情况大小启动新的以避免重新分配


Roy*_*tus 1

迭代 X 和 Y 确实是最快的选择,因为您有此Contains约束。我实在看不出还有什么其他办法。

但它不应该over foreachX,因为您无法修改使用 迭代的集合foreach

所以一个选择是:

for (int counterX = 0; counterX < X.Length; counterX++)
{
    for(int counterY = 0; counterY < Y.Length; counterY++)
    {
        if (X[counterX].Contains(Y[counterY]))
        {
            X.RemoveAt(counterX--);
            counterY = Y.Length;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该可以做到(请注意,此代码未经测试)。