C#:如何使用Linq / Lambda比较两个集合(System.Collection.Generic.List <t>)?</t>

时间:2012-03-05 06:15:49

标签: c# linq generics collections lambda

我有两个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_lstTwo中第m个的第n个位置应该替换为'X'。
  2. 示例

        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方法来解决这个问题。所以请帮我这样做。提前谢谢。

3 个答案:

答案 0 :(得分:5)

LINQ在这里不会帮到你; LINQ不是要修改集合。

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

相反,你可以写

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);

答案 1 :(得分:2)

嗯,如果我理解正确的话,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 extension method,其中包含两个列表的元素,如zip。外拉链基本上创建了单词对以进行迭代,第二个创建了一个蒙版(从第二个单词中取出所有字符,除非第一个单词在该位置有X)。

另请注意,这会创建一个新的字符串序列,而不是替换l_lstTwo中的字符串 - 这就是Linq的做事方式。

答案 2 :(得分:2)

您可以使用.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]));
相关问题