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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:05:54  来源:igfitidea点击:

Compare two List<int>

c#

提问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

I would use the Intersectand Exceptmethods:

我会使用IntersectExcept方法:

dups = groupA.Intersect(groupB).ToList();
distinct = groupA.Except(groupB).ToList();

回答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 numslist goes from

它不会删除 4 的值,因为当我删除 2 的值时,(for i=0nums列表从

//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 foreachstatement 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)

(假设我正确理解你想要做什么)