如何从另一个列表中减去一个列表?
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
无法处理多个值。
答案 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)
答案 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))