【问题标题】:Group objects by equality按相等分组对象
【发布时间】:2009-12-07 15:35:53
【问题描述】:

我有一个对象集合,我想使用如下所示的方法来比较它们的相等性:

bool AreEqual(MyObject O1, MyObject O2);

将所有相等的对象分组的最性能友好的方式是什么?显而易见的答案是将每个对象与集合中的所有其他对象进行比较,但这会损害性能(我相信 N ^ N)。

LINQ group by operator 能否提供解决方案?

编辑:

我或许应该将 MyObject 命名为TheyObject,因为我无法修改它的实现(而且它没有实现 IComparable)。这意味着我可能会使用 ICR 的解决方案。

【问题讨论】:

    标签: c#


    【解决方案1】:

    您不需要将每个对象与每个其他对象进行比较,您需要将每个对象与每个组(例如组中的第一项)进行比较,如果它不匹配任何对象(或者如果这是第一项)。

    可能看起来像:

    public static IEnumerable<IEnumerable<T>> Group<T>(IEnumerable<T> items)
        where T : IEquatable<T>
    {
        IList<IList<T>> groups = new List<IList<T>>();
    
        foreach (T t in items)
        {
            bool foundGroup = false;
    
            foreach (IList<T> group in groups)
            {
                Debug.Assert(group.Count() >= 1);
                if (group[0].Equals(t))
                {
                    group.Add(t);
                    foundGroup = true;
                    break;
                }
            }
    
            if (!foundGroup)
            {
                IList<T> newGroup = new List<T>() { t };
                groups.Add(newGroup);
            }
        }
    
        foreach (IList<T> group in groups)
        {
            yield return group;
        }
    }
    

    当然,这在 Linq 中已经为您完成了,人们在上面已经概述了如何使用。我只是想证明该算法比将每个项目与每个项目进行比较要好一点。

    注意该算法依赖于等式关系是可传递的假设——即如果a等于b,b等于c,那么a等于c。虽然我不太确定您将如何对非传递项进行分组。

    【讨论】:

    • 感谢您的样品。经您的许可,我想在我的项目中使用它。最后几行特别有趣。与简单的“返回组”相比,最终循环有什么好处? ?
    • 就像我说的,我仍然会推荐 LINQ 解决方案。它的作用几乎相同,但它已经为你编写好了。我提供样本的原因是为了让您了解这种算法的工作原理。最后几行的目的是因为我喜欢返回最通用的适用类型——在本例中为 IEnumerable。但是为了构造它们,您需要使用 IList 来拥有 Add 方法。 C# 目前无法解决如何将 IEnumerable> 转换为 IEnumerable> 的方法,因此您需要手动生成每个组。好处是它可以编译:)
    • 这确实不是一个好的实现,因为它是 O(n^2)。请使用现有的GroupByLinq 扩展方法。
    【解决方案2】:

    我建议将IComparable interface 用于 MyObject 类,然后尝试对其进行分组,例如完成herehere

    【讨论】:

      【解决方案3】:

      如果您打算使用 LINQ,可以使用IEqualityComparerHere 是使用 IComparer 和 IEqualityComparer 的示例

      我会使用 LINQ 来比较所有元素。如果您想获取不同对象的列表,我会这样做(伪代码)

      1. 实现 IEqualityComparer,比如 ObjectEqualityComparer 实现 IEqualityComparer
      2. var result = sourceList.Distinct(objectEqualityComparer 的一个实例)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        • 1970-01-01
        • 2021-10-14
        相关资源
        最近更新 更多