我正在写一个小程序来比较两个List.如果值相同,我将它们添加到列表dup中,如果它们不同,我将它们添加到distinct.我注意到我的一些值被添加了,有些则没有,经过一段时间的调试后,我不确定是什么问题.有人可以放一点光吗?谢谢.
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]);
}
Run Code Online (Sandbox Code Playgroud)
Mas*_*uso 40
dups = groupA.Intersect(groupB).ToList();
distinct = groupA.Except(groupB).ToList();
Run Code Online (Sandbox Code Playgroud)
Abo*_*ish 14
问题的标题是“比较两个列表”,一些只对真/假结果感兴趣的人会想到这个问题
使用 Enumerable.SequenceEqual 方法
if (listA.SequenceEqual(listB))
{
// they are equal
}
Run Code Online (Sandbox Code Playgroud)
从列表中删除项目时,将向下移动剩余元素的索引.实质上,您使用for循环跳过一些项目.
尝试使用while循环,并在不删除项目时手动递增计数器.
例如,以下代码不正确
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]);
}
Run Code Online (Sandbox Code Playgroud)
如果将返回列表{4, 7, 10, 11}而不是仅返回{7, 11}.
它不会删除4的值,因为当我删除值2时,(for i=0)nums列表来自
//index 0 1 2 3 4 5 6
nums = {2, 4, 6, 7, 8, 10, 11}
Run Code Online (Sandbox Code Playgroud)
至
//index 0 1 2 3 4 5
nums = {4, 6, 7, 8, 10, 11}
Run Code Online (Sandbox Code Playgroud)
循环结束,i增加到1,并且引用的下一个项目nums[1]不是4,正如人们所期望的那样,但是6.因此实际上跳过了4的值,并且不执行检查.
每次修改正在迭代的集合时,您应该非常非常小心.例如,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
}
}
Run Code Online (Sandbox Code Playgroud)
你甚至可以分叉,就像
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
}
}
Run Code Online (Sandbox Code Playgroud)
或者你可以使用linq,像这样:
distinct.AddRange(groupA);
distinct.AddRange(groupB);
distinct = distinct.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)
和
dups.AddRange(groupA);
dups.AddRange(groupB);
dups = dups.GroupBy(i => i)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
Run Code Online (Sandbox Code Playgroud)
请注意,LINQ代码不会更改现有的groupA和groupB列表.如果你只想区分它们,你可以这样做
groupA = groupA.Distinct().ToList();
groupB = groupB.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)
您可以使用Linq轻松完成:
List<int> dups = groupA.Intersect(groupB).ToList();
List<int> distinct = groupA.Except(groupB).ToList();
Run Code Online (Sandbox Code Playgroud)
(假设我正确理解你要做的事)