如何从另一个列表中删除列表中的字符串

本文关键字:列表 删除列 字符串 删除 另一个 | 更新日期: 2023-09-27 18:36:33

我有 2 个列表,分别是列表 A 和列表 B。

我想删除列表 B 中位于列表 A 中的字符串,但我想以这种方式执行此操作:

如果列表 A 包含:"bar"、"bar"、"bar"、"foo"列表 B 包含:"bar"

它只删除 1 根柱,结果将是:"酒吧"、"酒吧"、"福"

我编写的代码删除了所有"bar":

List<string> result = listA.Except(listB).ToList();

如何从另一个列表中删除列表中的字符串

您可以尝试逐个删除它:

foreach (var word in listB)
    listA.Remove(word);

Remove 方法一次只会删除一个元素,并且在找不到该项时不会引发异常(但返回 false):https://msdn.microsoft.com/en-us/library/cd666k3e(v=vs.110).aspx

var listA = new List<string>() { "bar", "bar", "bar", "foo" };
var listB = new List<string>() { "bar" };
foreach (var word in listB){
  listA.Remove(word);
}

这是一种更有效的方法:

var countB = new Dictionary<string, int>(listB.Count);
foreach (var x in listB)
{
    int count;
    countB.TryGetValue(x, out count);
    countB[x] = count + 1;
}
listA.RemoveAll(x =>
{
    int count;
    if (!countB.TryGetValue(x, out count)) return false;
    if (count == 1)
        countB.Remove(x);
    else
        countB[x] = count - 1;
    return true;
});

这是一种更快的方法,但它可能会改变第一个列表元素的顺序。步骤:

  • 将 listA 映射到一个Dictionary<string, int>(我们称之为 listAMap ),其中 key 是列表的元素,值是该值在 listA 中出现的总数;
  • 遍历列表 B,对于列表 B 的每个元素,如果该元素在listAMap中,则减少其计数;
  • 使用 C# 字典的 Keys 属性获取listMapA的键,并循环访问所有键。对于具有正值的每个键,将该键添加到另一个列表中,其计数时间的总和。因此,如果一个条目"bar" -> 2,则在新列表中添加"bar"两次。

算法的总运行时间为 O(m + n),其中 m 和 n 是两个原始列表中的元素数。它比这里提到的具有 O(m * n) 运行时间的其他方法运行时间更好。显然,此算法使用更多空间。


上述算法的支持代码:

//Step-1: Create the dictionary...
var listAMap = new Dictionary<string, int>();
foreach (var listAElement in listA)
{
    listAMap.ContainsKey(listAElement) ? listAMap[listAElement]++ : listAMap.Add(listAElement, 1);
}
// Step-2: Remove the listB elements from dictionary...
foreach (var listBElement in listB)
{
    if (listAMap.Contains(listBElement)) listAMap[listBElement]--;
}
//Step-3: Create the new list from pruned dictionary...
var prunedListA = new List<string>();
foreach (var key in listAMap.Keys)
{
    if (listAMap[key] <= 0) continue;
    for (var count = 0; count < listAMap[key]; count++)
    {
        prunedListA.Add(key);
    }
}
//prunedListA contains the desired elements now.