两个列表之间的区别保留重复

我有两个列表:

var list1 = new List<string> { "A", "A", "B", C" };
var list2 = new List<string> { "A", "B" };

我想列出一个列表

var result = new[] { "A", "C" };

当名单是所有元素list1从删除list2 ,我不认为有这个,因为一个LINQ扩展方法Except删除重复。

非LINQ方式做到这一点将是:

var tempList = list1.ToList();
foreach(var item in list2)
{
    tempList.Remove(item);
}

但我想知道是否有我可能错过的Linq扩展方法。

编辑:

因为这里可能没有任何扩展方法。

public static class LinqExtensions
{
    public static IEnumerable<T> RemoveRange<T>(this IEnumerable<T> source, IEnumerable<T> second)
    {
        var tempList = source.ToList();

        foreach(var item in second)
        {
            tempList.Remove(item);
        }

        return tempList;
    }

    public static IEnumerable<TFirst> RemoveMany<TFirst, TSecond>(this IEnumerable<TFirst> source, IEnumerable<TSecond> second, Func<TSecond, IEnumerable<TFirst>> selector)
    {
        var tempList = source.ToList();

        foreach(var item in second.SelectMany(selector))
        {
            tempList.Remove(item);
        }

        return tempList;
    }
}

用法:

list1.RemoveRange(list2)

看你的例子,我认为你的意思是“从列表1中删除了list2中的所有元素”:

var lookup2 = list2.ToLookup(str => str);

var result = from str in list1
             group str by str into strGroup
             let missingCount 
                  = Math.Max(0, strGroup.Count() - lookup2[strGroup.Key].Count())
             from missingStr in strGroup.Take(missingCount)
             select missingStr;

如果你不关心结果元素的顺序,你可以用LINQ的GroupBy

var a = new List<string>{"A","A", "B", "C"};
var b = new List<string>{"A", "B"};
var res  =  a.Select(e => new {Key=e, Val=1})
    .Concat(b.Select(e => new {Key=e, Val=-1}))
    .GroupBy(e => e.Key, e => e.Val)
    .SelectMany(g => Enumerable.Repeat(g.Key, Math.Max(0, g.Sum())))
    .ToList();

这是一个关于ideone的演示。

我必须承认你的解决方案比我的解决方案简单得多,所以它应该被视为一种好奇心,这也是证明LINQ也可以完成的一种方式。

下面是它的工作方式:对于第一个列表中的每个元素,我们添加一个键值对,其中1 ; 对于第二个列表中的每个元素,我们添加一个带有-1的键值对。 然后,我们将所有元素按键分组,总计分数和负数,并产生与总数一样多的键,确保在结果为负时我们不会选择任何内容。


不是LINQ,而是一行代码:

list2.ForEach(l => list1.Remove(l));

顺便说一句...如果List<int>具有AddRange类的AddRange但同时移除一堆物品,那将会很好。

链接地址: http://www.djcxy.com/p/70645.html

上一篇: Difference between two lists preserving duplicates

下一篇: How do I know which libraries to link against?