2013-08-21 278 views
2

我有一些代码,我写了下面这个基本模式。我期待看看是否有更好,更简洁或更好的表现方式来实现其目标。目标是将一个列表中的项目与另一个列表中的项目进行比较,如果匹配则执行操作。我得到它的唯一方法是工作,下面的想法,但我是新来的C#和.NET,我不知道是否有更好的方法。嵌套while循环替代

list A 
list B 
int counter; 
int counter2; 
while (counter < comparison item) 
{ 
    while (counter2 < comparison item 2) 
    { 
     if (A[counter] == B[counter2]) 
     { 
      // do stuff 
     } 
     counter2++; 
    } 
    counter++; 
} 
+0

LINQ是一种可能性,但它在功能上是相同的东西。 – siride

+0

您也可以事先对列表进行排序,并执行合并连接类型操作。根据列表的大小和你计划在做什么样的操作,它可能会更快。一如既往,衡量。 – siride

回答

3

这个双循环结构很简单,但它不是高性能的。问题是比较的数量:如果第一组有N项目,第二组有M,那么将会有N*M比较。每套有1,000件商品,我们正在谈论1,000,000个比较。

更好的方法是散列第一组的项目,然后在第二组中搜索散列项目。由于散列在固定的时间里完成,你可以在M+N操作做到这一点,或者两套各1,000个项目约2000:

var setA = new HashSet<int>(listA); 
foreach (var b in listB) { 
    if (setA.Contains(b)) { 
     ... 
    } 
} 

LINQ库让您的代码甚至更少行做到这一点:

foreach (var ab in listA.Intersect(listB)) { 
    ... 
} 
+0

谢谢你的答案,对于第二个例子,你会使用列表作为List对象还是HashSet对象? – wondergoat77

+0

@ wondergoat77无论你传递给LINQ的容器如何:它在内部使用一个基于散列的容器来进行合并,将输入视为“IEnumerable '。 – dasblinkenlight

+0

真棒,谢谢你的提示! – wondergoat77

1

如果不需要改变清单那么你应该使用一个foreach循环。

foreach (var itemA in A) 
{ 
    foreach (var itemB in B) 
    { 
     if (itemA == itemB) {} 
    } 
} 

如果确实需要更改列表那么你应该使用一个for循环。

for (var i = 0; i < A.Count; i++) 
{ 
    for (var j = 0; j < B.Count; j++) 
    { 
     if (A[i] == B[j]) {} 
    } 
} 

如果两个列表进行排序你可以以通过列表会更有效地做到这一点。

int i = 0; 
int j = 0; 

while (A.Length <= i && B.Length <= j) 
{ 
    if (A[i] == B[j]) 
    { 
     // items are equal 
     i++; 
     j++; 
    } 
    else if (A[i] > B[j]) // Comparison of the ordered value, could be a property on the item. 
    { 
     j++; // increment B's counter 
    } 
    else 
    { 
     i++; // increment A's counter 
    } 
}