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" }
注意:两个列表都将包含相同数量的元素,并且每个元素的长度都将相同。
比较就像
- 如果
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方法来解决这个问题。所以请帮我做这个。提前谢谢。
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的做法。