C#:如何使用Linq/Lambda比较两个集合(System.Collection.Generic.List<;T

本文关键字:Collection System 集合 Generic List lt 两个 Linq 何使用 Lambda 比较 | 更新日期: 2023-09-27 18:26:35

我有两个类似的String集合

 List<String> l_lstOne = new List<String> { "100", "1X0", "X11", "XXX" }, 
    l_lstTwo = new List<String> { "000", "110", "100", "000" };

我需要比较这两个列表,并使第二个列表像

    { "000", "1X0", "X00", "XXX" }

注意:两个列表都将包含相同数量的元素,并且每个元素的长度都将相同。

比较就像

  1. 如果l_lstOne中的第m个元素的第n个位置有"X",则l_lstTow中第m个的第n位置应替换为"X"

示例

    l_lstOne            l_lstTwo        Output
      100                 000             000
      1X0                 110             1X0
      X11                 100             X00

所以,为了解决这个问题,我使用了嵌套for循环,这是我的源代码,

 for (int l_nIndex = 0; l_nIndex < l_lstTwo.Count; l_nIndex++)
        {
            String l_strX = String.Empty;
            for (int l_nInnerIndex = 0; l_nInnerIndex < l_lstTwo[l_nInnerIndex].Length; l_nInnerIndex++)
            {
                l_strX += l_lstOne[l_nIndex][l_nInnerIndex] == 'X' ? 'X' : l_lstTwo[l_nIndex][l_nInnerIndex];
            }
            l_lstTwo[l_nIndex] = l_strX;
        }   

这段代码运行良好,但问题是,它需要更多的时间来执行,即处理200000个元素,每个元素的长度为16,几乎需要600毫秒。

此外,我需要一个Linq或Lambda方法来解决这个问题。所以请帮我做这个。提前谢谢。

C#:如何使用Linq/Lambda比较两个集合(System.Collection.Generic.List<;T

LINQ在这里对您没有帮助;LINQ并不意味着要修改集合。

通过构建char[]而不是string,可以大大加快代码的编写速度;现在,由于+=,您正在构建320万个string对象。

相反,你可以写

char[] l_strX = new char[l_lstTwo[l_nInnerIndex].Length];
for (int l_nInnerIndex = 0; l_nInnerIndex < l_lstTwo[l_nInnerIndex].Length; l_nInnerIndex++)
{
    l_strX[l_nInnerIndex] = l_lstOne[l_nIndex][l_nInnerIndex] == 'X' ? 'X' : l_lstTwo[l_nIndex][l_nInnerIndex];
}
l_lstTwo[l_nIndex] = new string(l_strX);

您可以在.NET 3.5 中使用以下语句

    IEnumerable <String> result =
        Enumerable.Range(0, l_lstOne.Count)
            .Select(i => Enumerable.Range(0, l_lstOne[i].Length)
                .Aggregate(string.Empty, (innerResult, x) => innerResult += l_lstOne[i][x] == 'X' ? 'X' : l_lstTwo[i][x]));

Mh,如果我理解正确,l_lstOne中的单词将充当l_lstTwo中单词的掩码,其中掩码是透明的,除非它是X。这个怎么样:

l_lstOne.Zip(l_lstTwo, 
    (w1, w2) => new String(w1.Zip(w2, (c1, c2) => c1 == 'X' ? c1 : c2).ToArray())))

Zip是.NET 4中提供的一个Linq扩展方法,它将两个列表的元素像zip一样组合在一起。外部zip基本上创建要迭代的单词对,第二个创建掩码(从第二个单词中获取所有字符,除非单词一在该位置有X)。

还要注意,这会创建一个新的字符串序列,而不是替换l_lstTwo中的字符串序列——这是Linq的做法。