【问题标题】:How to perform set subtraction on arrays in C#?如何在 C# 中对数组执行集合减法?
【发布时间】:2023-03-18 23:57:01
【问题描述】:

在给定 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" }

【问题讨论】:

    标签: c# arrays set-operations


    【解决方案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 中删除重复项。说清楚:

    1. { 'A', 'A' } - { 'A' } == { 'A' }
    2. { '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());
    猜你喜欢
    • 2016-05-07
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多