c# 从第二个列表中删除元素

c# remove elements from 2nd list

我想从 list2 中删除属于 list1 的所有元素。 我注意到如果我的代码有例如两个列表中都有 50k 个元素。我遍历 list1 中的所有元素,如果元素包含在 list2 中,我就从 list2 中删除该元素。 什么是有效的方法?

        public static int RemoveDuplicatesFromSecondRange(List<string> list1, List<string> list2)
        {
           int removed = 0;

           foreach (string el in list1)
           {
              list2.Remove(el);
              removed++;
           }

           return removed;
        }

我会留给你进行性能测试...

public static int RemoveDuplicatesFromSecondRange2(List<string> list1, List<string> list2)
{
  var exCount = list2.Select(s => s).Except(list1).Count();
  return list2.Count - exCount;
}

这样做是创建第三个列表,其中仅包含出现在 list2 而不是出现在 list1 中的元素。

在内部,我相信 LINQ 使用优化,创建一个 HashSet 有效地提供类似这样的东西...

public static int RemoveDuplicatesFromSecondRange3(List<string> list1, List<string> list2)
{
  var h = new HashSet<string>(list1);
  var exCount = list2.Select(s => s).Except(h).Count();
  return list2.Count - exCount;
}

(不是在每次测试 list2 的每个元素时扫描整个 list1,它首先创建一个索引数据结构,以便在列表中更快地查找)。

您的代码似乎只需要计数,但您的问题是您想要一个删除条目的列表...

public static List<string> RemoveDuplicatesFromSecondRange4(List<string> list1, List<string> list2)
{
  return list2.Select(s => s).Except(list1).ToList();
  /* OR
  var h = new HashSet<string>(list1);
  return list2.Select(s => s).Except(h).ToList();
  */
}

可能这个解决方案是有效的。因为它是 复杂度为 O(N)

public static int RemoveDuplicatesFromSecondRange(List<string> list1, List<string> list2)
{
  var beforeCount = list2.Count;

  var inList2Only = list2.Except(list1).ToList();

  list2.Clear();
  list2.AddRange(inList2Only);

  return beforeCount - inList2Only.Count;
}