C#从另一个列表中减去一个列表或检查一个列表是否完全包含在另一个列表中

时间:2016-09-07 20:31:58

标签: c# .net list

如何从另一个列表中减去一个列表?

  List<string> l1 = new List<string> { "abc", "abc", "abc", "def" };
  List<string> l2 = new List<string> { "abc" };
  var r = l1.Except(l2).ToList();

这样做会导致r =&gt; &#34; DEF&#34; 而不是r =&gt; &#34; abc&#34;,&#34; abc&#34;,&#34; def&#34;。 我的意思是,第二个列表只包含&#34; abc&#34;一度。所以我想只删除一个&#34; abc&#34;第一个清单。

顺便说一句:有没有办法检查一个列表是否完全包含在另一个列表中? list1仅包含&#34; abc&#34;一次,list2包含&#34; abc&#34;两次,list2不包含在list1中。 Except无法处理多个值。

5 个答案:

答案 0 :(得分:5)

您可以编写自己的扩展方法 MyExcept

public static IEnumerable<T> MyExcept<T>(this IEnumerable<T> orgList, IEnumerable<T> toRemove)
{
    var list = orgList.ToList();
    foreach(var x in toRemove)
    {
        list.Remove(x);
    }
    return list;
}

根据Alexei Levenkov的评论,稍作改进......

public static IEnumerable<T> MyExcept2<T>(this IEnumerable<T> orgList, IEnumerable<T> toRemove)
{
    var list = orgList.OrderBy(x => x).ToList();
    foreach (var x in toRemove)
    {
        var inx = list.BinarySearch(x);
        if (inx >= 0) list.RemoveAt(inx);
    }
    return list;
}

答案 1 :(得分:4)

Except不起作用,因为它将其操作数视为集合。

解决此问题的一种方法是创建计数,减去它们,然后重新创建列表:

// Make word counts for l1 and l2
var c1 = l1.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count());
var c2 = l2.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count());
// Make a count of the difference between the two
var diff = new Dictionary<string,int>();
foreach (var p in c1) {
    int sub;
    if (!c2.TryGetValue(p.Key, out sub)) {
        sub = 0;
    }
    diff[p.Key] = p.Value - sub;
}
// Reconstruct the result from counts
var res = diff.SelectMany(p => Enumerable.Repeat(p.Key, p.Value)).ToList();

该算法为O(M + N)

Demo.

答案 2 :(得分:2)

List的Remove方法删除列表中第一次出现的字符串:

        List<string> l1 = new List<string> { "abc", "abc", "abc", "def" };
        List<string> l2 = new List<string> { "abc", "abc" };
        foreach (string sl2 in l2)
        {
            l1.Remove(sl2);
        }

因此,在这个例子中,l1只包含“abc”和“def”。

答案 3 :(得分:0)

我认为你应该为这个编写一个自定义代码,如下所示:

public class ChromeDriver extends RemoteWebDriver
implements LocationContext, WebStorage {}

public class RemoteWebDriver implements WebDriver, JavascriptExecutor,
FindsById, FindsByClassName, FindsByLinkText, FindsByName,
FindsByCssSelector, FindsByTagName, FindsByXPath,
HasInputDevices, HasCapabilities, TakesScreenshot {}

你可以做得更好,这只是一个例子^^

答案 4 :(得分:0)

a.delete_at(a.index(a.max))