C#比较两个有序列表以添加更新的值

时间:2014-07-31 16:01:24

标签: c# list overlap

我有一个数据源包含6个项目,订单很重要,每次检查时都会更新。
这是最初的清单
列表1:

  • 小鼠

然后我等待,列表更新了一些数量,顶部项目被删除,新的项目被添加。这是我获取的新列表 列表2:

  • 小鼠
  • 仓鼠

在这种情况下,我想找到一种方法来找出新增的值,cat + hamster。

我的实际问题有38个项目和每项检查的来源,0到38个项目已添加到底部。但是我不能查看最新的38个项目。

示例

        List<string> list1 = new List<string>();
        List<string> list2 = new List<string>();

        list1.Add("dog");
        list1.Add("cat");
        list1.Add("fish");
        list1.Add("cat");
        list1.Add("cat");
        list1.Add("mouse");

        list2.Add("fish");
        list2.Add("cat");
        list2.Add("cat");
        list2.Add("mouse");
        list2.Add("cat");
        list2.Add("hamster");

        Console.WriteLine("List 1" + Environment.NewLine);

        foreach(string item in list1)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine(Environment.NewLine + "List 2" + Environment.NewLine);

        foreach (string item in list2)
        {
            Console.WriteLine(item);
        }

        var newItems = list2.Except(list1);

        Console.WriteLine(Environment.NewLine + "New Items" + Environment.NewLine);

        foreach (string item in newItems)
        {
            Console.WriteLine(item);
        }

使用Except,结果是'hamster',因为cat确实存在于第一个列表中,除了似乎没有检查顺序(有没有办法?)

现在,这似乎很容易,而且应该已经回答了,所以我认为我只是没有在搜索中键入正确的内容。

任何帮助表示感谢。

修改 我可以想象一个解决方案,循环遍历增加大小的列表,从列表1的最后一个值和列表2的第一个值开始,然后使用SequenceEqual()直到false来计算有多少项重叠并从那里开始。 这会是一个很好的解决方案吗?

使用解决方案 我在编辑中提到并通过使用SequenceEqual()

比较匹配增加大小的列表来循环

我确定这是低效的,但这不会对我造成问题。如果有人知道一个更好的技巧,那就太好了。

        int size1 = list1.Count();
        int size2 = list2.Count();

        int i;
        for (i = 1; i <= size2; i++)
        {
            List<string> aList = list1.GetRange(size1 - i, i);
            List<string> bList = list2.GetRange(0, i);
            if(aList.SequenceEqual(bList))
            {
                break;
            }
        }

        int totalAdded = size2 - i;
        List<string> newItemsList = list2.GetRange(i, totalAdded);

        foreach (string item in newItemsList)
        {
            Console.WriteLine(item);
        }

        Console.ReadLine();

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您是否希望使用新项目创建第三个列表?或至少找到新项目:

List<string> newItems = new List<string>();
newItems.AddRange(list2.FindAll(s=> !list1.Contains(s)));

答案 1 :(得分:0)

StriplingWarrior在评论中提到的问题非常重要。虽然它的可能性很低,但解决方案应该适用于所有情况。

我建议您更改数据结构并在实体旁边添加整数。整数称为 ID ,它显示ID = 3的猫与ID = 7的猫之间的差异。所以你永远不会对你正在寻找哪只猫感到困惑对

新结构的最佳结构称为 Dictionary

我在下面更改了您的代码,结果是 cat 仓鼠

        int incrementalID = 0;
        Dictionary<int, string> list1 = new Dictionary<int, string>();
        Dictionary<int, string> list2 = new Dictionary<int, string>();

        list1.Add(incrementalID++, "dog");    //ID = 0
        list1.Add(incrementalID++, "cat");     //ID = 1
        list1.Add(incrementalID++, "fish");    //ID = 2
        list1.Add(incrementalID++, "cat");     //ID = 3
        list1.Add(incrementalID++, "cat");     //ID = 4
        list1.Add(incrementalID++, "mouse");   //ID = 5

        list2 = new Dictionary<int, string>(list1);
        list2.Remove(0);
        list2.Remove(1);
        list2.Add(incrementalID++, "cat");      //ID = 6
        list2.Add(incrementalID++, "hamster");  //ID = 7;

        Console.WriteLine("List 1" + Environment.NewLine);

        foreach (string item in list1.Values)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine(Environment.NewLine + "List 2" + Environment.NewLine);

        foreach (string item in list2.Values)
        {
            Console.WriteLine(item);
        }

        var newItems = list2.Except(list1);

        Console.WriteLine(Environment.NewLine + "New Items" + Environment.NewLine);

        foreach (KeyValuePair<int, string> item in newItems)
        {
            Console.WriteLine(item.Value);
        }