如何在 C# 中对数组执行集合减法?

Posted

技术标签:

【中文标题】如何在 C# 中对数组执行集合减法?【英文标题】:How to perform set subtraction on arrays in C#? 【发布时间】:2011-06-30 19:48:34 【问题描述】:

在给定 C# 中的两个数组的情况下,执行集合减法的最简单方法是什么?显然这是 Ruby 中的dead easy。基本上我只想从数组a 中删除数组b 中的元素:

string[] a = new string[]  "one", "two", "three", "four" ;
string[] b = new string[]  "two", "four", "six" ;
string[] c = a - b; // not valid

c 应该等于 "one", "three" b - a 将产生 "six"

【问题讨论】:

【参考方案1】:

如果您使用的是 Linq,您可以像这样使用 Except operator:

string [] c = a.Except(b).ToArray();

编辑: CodeInChaos 提出了一个很好的观点。如果a 包含重复项,它也会删除所有重复项。使其功能与 Ruby 版本完全相同的替代方法是:

string [] c = a.Where(x=>!b.Contains(x)).ToArray();

【讨论】:

请注意,这只会返回唯一元素。因此,如果您在 a 中有一个元素两次,它将只保留第一个。 太好了,谢谢——不知道我是怎么错过的。猜猜这个名字让我失望了。 替代方案将删除重复项! 请注意,您的替代代码是O(a.Length*b.Length)。为了让它更快,你需要从b 中构造一个HashSet<T> @xanatos - 这是正确的行为,从 A 中删除 B 中的所有元素。另一方面,我的替代方案将执行 'B','B' - 'A' = 'B','B'【参考方案2】:
public static IEnumerable<T> Minus<T>(this IEnumerable<T> enum1, IEnumerable<T> enum2)

    Dictionary<T, int> elements = new Dictionary<T, int>();

    foreach (var el in enum2)
    
        int num = 0;
        elements.TryGetValue(el, out num);
        elements[el] = num + 1;
    

    foreach (var el in enum1)
    
        int num = 0;
        if (elements.TryGetValue(el, out num) && num > 0)
        
            elements[el] = num - 1;
        
        else
        
            yield return el;
        
    

这不会从 enum1 中删除重复项。说清楚:

    'A', 'A' - 'A' == 'A' 'A', 'A' - 'A' ==

我做第一个,Enumerable.Except 做第二个。

【讨论】:

elements.Remove 应该是elements.Contains @Keltex,这个想法是你想删除它,因为它已经被计算在内。但是,我认为它应该是 List 而不是 HashSet,因为否则它不会考虑 a, a, a - a, a = a 不,它应该是字典,所以我仍然在 O(m * log(n)) 中(技术上可能是 O((m + 1) * log(n)) ) 使用 Linq,你可以做到var elements = enum2.GroupBy(el =&gt; el).ToDictionary(elg =&gt; elg.Key, elg =&gt; elg.Count());

以上是关于如何在 C# 中对数组执行集合减法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中对二维(矩形)数组进行排序?

如何根据用户输入在 C# 中对对象数组进行排序?

如何在 MongoDB 中对集合记录中的数组进行排序?

如何在 PHP/Eclipse 中对 foreach 循环中从数组中拉出的自定义对象进行智能感知?

如何在 Java 中对二维数组进行深拷贝?

如何使用 hdf5 文件中的一维数组并对它们执行减法、加法等操作?