问题 C#SortedSet 和相等


我对SortedSet的行为有点疑惑,请看下面的例子:

public class Blah
{
    public double Value { get; private set; }

    public Blah(double value)
    {
        Value = value;
    }
}

public class BlahComparer : Comparer<Blah>
{
    public override int Compare(Blah x, Blah y)
    {
        return Comparer<double>.Default.Compare(x.Value, y.Value);
    }
}

public static void main()
{
    var blahs = new List<Blah> {new Blah(1), new Blah(2), 
                                new Blah(3), new Blah(2)}

    //contains all 4 entries
    var set = new HashSet<Blah>(blahs); 

    //contains only Blah(1), Blah(2), Blah(3)
    var sortedset = new SortedSet<Blah>(blahs, new BlahComparer());
}

因此,如果Compare(x,y)返回0,SortedSet会丢弃条目。我可以阻止这种情况,这样我的SortedSet就像HashSet一样,只有在Equals()返回true时才丢弃条目吗?


3156
2017-12-22 12:53


起源

该 Comparer的文档 要说0表示'x等于y',但不是'没有排序'。我想你可以比较x和y的参考值 .Value 匹配。 - Rup


答案:


如果在值相等时提供备用比较并且比较方法将返回0,则可以执行此操作。在大多数情况下,这可能只是推迟问题而不是解决问题。正如其他人所指出的那样,SortedSet会丢弃重复项,当您提供自定义比较器时,它会使用它来确定重复性。

    static void Main(string[] args)
    {
        var blahs = new List<Blah>
                        {
                            new Blah(1, 0), new Blah(2, 1),
                            new Blah(3, 2), new Blah(2, 3)
                        };

        blahs.Add(blahs[0]);

        //contains all 4 entries
        var set = new HashSet<Blah>(blahs);

        //contains all 4 entries
        var sortedset = new SortedSet<Blah>(blahs, new BlahComparer());

    }
}

public class Blah
{
    public double Value { get; private set; }

    public Blah(double value, int index)
    {
        Value = value;
        Index = index;
    }

    public int Index { get; private set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

public class BlahComparer : Comparer<Blah>
{
    public override int Compare(Blah x, Blah y)
    {
        // needs null checks
        var referenceEquals = ReferenceEquals(x, y);
        if (referenceEquals)
        {
            return 0;
        }
        var compare = Comparer<double>.Default.Compare(x.Value, y.Value);
        if (compare == 0)
        {
            compare = Comparer<int>.Default.Compare(x.Index, y.Index);
        }
        return compare;
    }
}

4
2017-12-22 13:35





描述

SortedSet的: 您需要存储许多元素,并且您希望按排序顺序存储它们 消除所有重复 从数据结构。 SortedSet类型是C#语言和.NET Framework中System.Collections.Generic命名空间的一部分,它提供此功能。

根据MSDN Compare 方法返回

  • 小于零 如果x小于y。
  •  如果x等于y。
  • 大于零 如果x大于y。

更多信息

更新

如果你的 Bla 类实现 IComparable 并且您希望列表排序,您可以这样做。

var blahs = new List<Blah> {new Blah(1), new Blah(2), 
                            new Blah(3), new Blah(2)};
blahs.Sort();

如果你的 Bla 类  器物 IComparable 并且您希望您的列表可以使用 Linq (System.Linq命名空间)。

blahs = blahs.OrderBy(x => x.MyProperty).ToList();

8
2017-12-22 12:58



谢谢大胆的“消除所有重复”。在返回“0”之前,实现IComparer时必须确定200% - ilansch


你找不到对方 Blah(2) 因为你正在使用 Set

Set - A collection of well defined and **distinct** objects

MultiSet例如,允许重复的对象。


2
2017-12-22 13:04