查找从2个列表中添加和删除的元素

本文关键字:删除 元素 添加 2个 列表 查找 | 更新日期: 2023-09-27 18:02:59

我有

var list1 = new List<int> { 1, 2, 3 };
var list2 = new List<int> { 1, 2, 4 };

我想从这个:

listAdded: {4}
listRemoved: {2}

元素是不同的。

如何:

*Quickly find if list1 and list2 are the same (no changes)
*Get the list of changes (added & removed)?

我目前使用的是List<T>,但我对HashSet<T>开放,如果它会使事情更快。

查找从2个列表中添加和删除的元素

只需使用Except即可获得新集合中两个列表之间的差异,然后可以检查新集合的计数以查看它们是否有任何差异。

var removed = list1.Except(list2).ToList();
var added = list2.Except(list1).ToList();

然后你可以自由地对他们的计数做一个简单的if:

bool areDifferent = removed.Count > 0 || added.Count > 0;

或者如Kevin建议的:

bool areDifferent = removed.Any() || added.Any();

使用LINQ的伪代码-(删除-参见@meJustAndrew的答案以获得更好的LINQ实现)

你可以做一些O(n)如果列表是排序的:

int i = 0;
int j = 0;
while(i < list1.Count && j < list2.Count)
{
   if (list1[i] == list2[j])
   {
     ++i;
     ++j;
   }
   else if (list1[i] < list2[j])
   {
     removed.Add(list1[i]);
     ++i;
   }
   else // if (list1[i] > list2[j])
   {
     added.Add(list2[j]);
     ++j;
   }
}
if (i < list1.Count)
{
  removed.AddRange(list1.GetRange(i,list1.Count));
}
if (j < list2.Count)
{
  added.AddRange(list2.GetRange(j,list2.Count));
}

您可以创建一个派生自List<>的class,并覆盖Add()和Remove()。

Public class MyList<T> : List<T>
{
    private List<T> oldItems = new List<T>();
    private List<T> newItems = new List<T>();
    private List<T> items = new List<T>();
    public List<T> Items 
    {
        get { return items; }
        set { items = value; }
    }
    public void Add(T value)
    {
        Items.Add(value);
        newItems.Add(Items.Where(w=>w==value)); // must be the object in the "Items" list
    }
    public void Remove(T value)
    {
        Items.Remove(value);
        oldItems.Add(value); //value does not exist anymore in `Items`
    }
    public List<T> GetOldItems()
    {
        List<T> oldi = oldItems;
        oldItems.Clear();
        return oldi;
    }
    public List<T> GetNewItems() //
    {
        List<T> newi = newItems;
        newItems.Clear();
        return newi;
    }
}

那么你就有了一个包含新旧项目的列表。

当你添加一个项目,它将被注册,即使你删除一个项目。当您得到新的或旧的项目,寄存器将被清除。