我有两个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_lstTwo中第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方法来解决这个问题。所以请帮我这样做。提前谢谢。
答案 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]));