C# 比较两个 List<int>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14217261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Compare two List<int>
提问by jpavlov
I am writing a small program to compare two List. If the values are the same, I add them to list dups, if they are different, I add them to distinct. I noticed that some of my values are added and some are not, and after debugging for awhile, I am not certain what the problem is. Can someone shed a little light? Thanks.
我正在编写一个小程序来比较两个列表。如果值相同,我将它们添加到列表重复,如果它们不同,我将它们添加到不同。我注意到我的一些值被添加了一些没有,经过调试一段时间后,我不确定问题是什么。有人可以照亮一点吗?谢谢。
List<int> groupA = new List<int>();
List<int> groupB = new List<int>();
List<int> dups = new List<int>();
List<int> distinct = new List<int>();
groupA.Add(2);
groupA.Add(24);
groupA.Add(5);
groupA.Add(72);
groupA.Add(276);
groupA.Add(42);
groupA.Add(92);
groupA.Add(95);
groupA.Add(266);
groupA.Add(42);
groupA.Add(92);
groupB.Add(5);
groupB.Add(42);
groupB.Add(95);
groupA.Sort();
groupB.Sort();
for (int a = 0; a < groupA.Count; a++)
{
for (int b = 0; b < groupB.Count; b++)
{
groupA[a].CompareTo(groupB[b]);
if (groupA[a] == groupB[b])
{
dups.Add(groupA[a]);
groupA.Remove(groupA[a]);
groupB.Remove(groupB[b]);
}
}
distinct.Add(groupA[a]);
}
采纳答案by Massimiliano Peluso
回答by SWeko
When you remove an item from a list, you move the index of the remaining element down.
In essence, you are skipping some items using a for loop.
Try using a while loop, and manually increment the counter when you are not deleting an item.
从列表中删除项目时,会将剩余元素的索引向下移动。本质上,您是在使用 for 循环跳过一些项目。
尝试使用 while 循环,并在不删除项目时手动增加计数器。
For example, the following code is incorrect
例如下面的代码是不正确的
List<int> nums = new List<int>{2, 4, 6, 7, 8, 10, 11};
for (int i = 0; i < nums.Count; i++)
{
if (nums[i] % 2 == 0)
nums.Remove(nums[i]);
}
If will return the list {4, 7, 10, 11}
instead of just {7, 11}
.
If 将返回列表,{4, 7, 10, 11}
而不仅仅是{7, 11}
.
It will not remove the value of 4, because, when I remove the value of 2, (for i=0
) the nums
list goes from
它不会删除 4 的值,因为当我删除 2 的值时,(for i=0
)nums
列表从
//index 0 1 2 3 4 5 6
nums = {2, 4, 6, 7, 8, 10, 11}
to
到
//index 0 1 2 3 4 5
nums = {4, 6, 7, 8, 10, 11}
The loop finishes, the i is incremented to 1, and the next item referenced is nums[1]
, which is not 4 as one would intuitively expect, but 6. So in effect the value of 4 is skipped, and the check is not executed.
循环结束, i 增加到 1,引用的下一项是nums[1]
,它不是直观预期的 4,而是 6。因此实际上跳过了 4 的值,并且不执行检查。
You should be very, very careful each time when you are modifying the collection you are iterating. For example, the foreach
statement will throw an exception if you even try this. In this case you could use a while like
每次修改正在迭代的集合时,您都应该非常非常小心。例如,foreach
如果您尝试这样做,该语句将引发异常。在这种情况下,您可以使用一段时间
List<int> nums = new List<int>{2, 4, 6, 7, 8, 10, 11};
int i = 0;
while (i < nums.Count)
{
if (nums[i] % 2 == 0)
{
nums.Remove(nums[i])
}
else
{
i++; //only increment if you are not removing an item
//otherwise re-run the loop for the same value of i
}
}
of you could even fork the for, like
你甚至可以分叉 for,比如
for (int i = 0; i < nums.Count; i++)
{
if (nums[i] % 2 == 0)
{
nums.Remove(nums[i]);
i--; //decrement the counter, so that it will stay in place
//when it is incremented at the end of the loop
}
}
Alternatively you could use linq, like this:
或者,您可以使用 linq,如下所示:
distinct.AddRange(groupA);
distinct.AddRange(groupB);
distinct = distinct.Distinct().ToList();
and
和
dups.AddRange(groupA);
dups.AddRange(groupB);
dups = dups.GroupBy(i => i)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
Note that the LINQ code will not alter your existing groupA and groupB lists. If you just want to distinct them, you could just do
请注意,LINQ 代码不会改变您现有的 groupA 和 groupB 列表。如果你只是想区分它们,你可以这样做
groupA = groupA.Distinct().ToList();
groupB = groupB.Distinct().ToList();
回答by Thomas Levesque
You can easily do it with Linq:
您可以使用 Linq 轻松完成:
List<int> dups = groupA.Intersect(groupB).ToList();
List<int> distinct = groupA.Except(groupB).ToList();
(assuming I correctly understood what you were trying to do)
(假设我正确理解你想要做什么)