是否有类似 SortedSet 的容器来对不可比较的对象进行分组?
Is there a SortedSet-like container that groups non-comparable objects?
我有一些对象想放入一个关联容器中,该容器按不可比较的字段值对它们进行分组。所以如果我有以下内容:
using System.Collections.Generic;
using Pair = System.Tuple<Penguin, int>;
class Penguin {}
class Whatever {
public static void Main(string[] args) {
Penguin emperor = new Penguin(),
adelie = new Penguin(),
batmanVillain = new Penguin();
var okay = new HypotheticalCollection<Pair>(5);
okay.Add(new Pair(emperor, 1) );
okay.Add(new Pair(adelie, 2) );
okay.Add(new Pair(batmanVillain, 3) );
okay.Add(new Pair(emperor, -500) );
okay.Add(new Pair(batmanVillain, 5) );
}
}
并且我遍历了 HypotheticalCollection,我想同时看到两个 emperor
条目和两个 batmanVillain
条目,但我不在乎哪个是第一个。但是,我希望能够以对数时间查找条目。
如果我使用 C++,我会按地址对 Penguin
进行排序,但我在 C# 中没有那么奢侈。现在我通过为每个对象分配一个序列号来处理它,但这感觉有点老套,我不希望有额外的 space 开销。有没有更好的方法,也许是 ReferenceLessThan
函数之类的?
选项 1:(建议)
public static class Whatever
{
class Penguin
{
private Guid id = Guid.NewGuid();
public Guid GetId() { return id; }
}
public static void Main(string[] args)
{
Penguin emperor = new Penguin(),
adelie = new Penguin(),
batmanVillain = new Penguin();
var okay = new List<KeyValuePair<Penguin, int>>();
okay.Add(new KeyValuePair<Penguin, int>(emperor, 1));
okay.Add(new KeyValuePair<Penguin, int>(adelie, 2));
okay.Add(new KeyValuePair<Penguin, int>(batmanVillain, 3));
okay.Add(new KeyValuePair<Penguin, int>(emperor, -500));
okay.Add(new KeyValuePair<Penguin, int>(batmanVillain, 5));
okay.Sort((a, b) => a.Key.GetId().CompareTo(b.Key.GetId()));
// Iterate 'okay'
}
}
方案2是在排序比较函数中使用对象地址,根据this is not a fix address and can be changed by the CLR. In addition, getting the address requires to build your app with unsafe flag. If you claim that option 1 feels "hacky", so csharaply option 2 is super "hacky". And a GUID是128位整数(16字节)。
我有一些对象想放入一个关联容器中,该容器按不可比较的字段值对它们进行分组。所以如果我有以下内容:
using System.Collections.Generic;
using Pair = System.Tuple<Penguin, int>;
class Penguin {}
class Whatever {
public static void Main(string[] args) {
Penguin emperor = new Penguin(),
adelie = new Penguin(),
batmanVillain = new Penguin();
var okay = new HypotheticalCollection<Pair>(5);
okay.Add(new Pair(emperor, 1) );
okay.Add(new Pair(adelie, 2) );
okay.Add(new Pair(batmanVillain, 3) );
okay.Add(new Pair(emperor, -500) );
okay.Add(new Pair(batmanVillain, 5) );
}
}
并且我遍历了 HypotheticalCollection,我想同时看到两个 emperor
条目和两个 batmanVillain
条目,但我不在乎哪个是第一个。但是,我希望能够以对数时间查找条目。
如果我使用 C++,我会按地址对 Penguin
进行排序,但我在 C# 中没有那么奢侈。现在我通过为每个对象分配一个序列号来处理它,但这感觉有点老套,我不希望有额外的 space 开销。有没有更好的方法,也许是 ReferenceLessThan
函数之类的?
选项 1:(建议)
public static class Whatever
{
class Penguin
{
private Guid id = Guid.NewGuid();
public Guid GetId() { return id; }
}
public static void Main(string[] args)
{
Penguin emperor = new Penguin(),
adelie = new Penguin(),
batmanVillain = new Penguin();
var okay = new List<KeyValuePair<Penguin, int>>();
okay.Add(new KeyValuePair<Penguin, int>(emperor, 1));
okay.Add(new KeyValuePair<Penguin, int>(adelie, 2));
okay.Add(new KeyValuePair<Penguin, int>(batmanVillain, 3));
okay.Add(new KeyValuePair<Penguin, int>(emperor, -500));
okay.Add(new KeyValuePair<Penguin, int>(batmanVillain, 5));
okay.Sort((a, b) => a.Key.GetId().CompareTo(b.Key.GetId()));
// Iterate 'okay'
}
}
方案2是在排序比较函数中使用对象地址,根据this is not a fix address and can be changed by the CLR. In addition, getting the address requires to build your app with unsafe flag. If you claim that option 1 feels "hacky", so csharaply option 2 is super "hacky". And a GUID是128位整数(16字节)。