使用 HashSet 作为字典键 - 比较所有元素
Use HashSet as Dictionary Key - Compare all elements
我正在检查一组边是否已经包含 2 个点之间的连接。
我想使用包含 2 个向量的 HashSet
作为 Dictionary
键。然后我希望能够调用一个性能Dictionary.ContainsKey(hashSet)
。我希望 contains/equality 检查依赖于集合中的向量。
费。如果我将 HashSet [V000 V001]
添加到字典中。我想让 Dictionary.ContainsKey(HashSet [V001 V000])
return 为真。 (HashSet,所以顺序可以不同,只是元素相同)
问题似乎是,Dictionary.ContainsKey()
方法确实将单独创建的 HashSets
视为不同的对象,尽管它们包含相同的元素。
Dictionary<HashSet<Vector3>, Vector3> d = new Dictionary<HashSet<Vector3>, Vector3>();
HashSet<Vector3> s = new HashSet<Vector3>();
s.Add(Vector3.one);
s.Add(Vector3.zero);
d.Add(s);
HashSet<Vector3> s2 = new HashSet<Vector3>();
s2.Add(Vector3.zero);
s2.Add(Vector3.one);
bool doesContain = d.ContainsKey(s2); // should be true
您还可以建议一种更好的方法来执行此操作'Contains()' 高效检查。
HashSet
类型不执行您想要开箱即用的相等比较。它仅具有引用相等性。
要获得您想要的内容,您需要一个新类型来用作字典键。新类型将有一个 HashSet 属性,并重载 Equals()
和 GetHashCode()
,此时也可以实现 IEquatable
。
我会帮你入门的:
public class HashKey<T> : IEquatable<HashKey<T>>
{
private HashSet<T> _items;
public HashSet<T> Items
{
get {return _items;}
private set {_items = value;}
}
public HashKey()
{
_items = new HashSet<T>();
}
public HashKey(HashSet<T> initialSet)
{
_items = initialSet ?? new HashSet();
}
public override int GetHashCode()
{
// I'm leaving this for you to do
}
public override bool Equals(Object obj)
{
if (! (obj is HashKey)) return false;
return this.GetHashCode().Equals(obj.GetHashCode());
}
public bool Equals(HashSet<T> obj)
{
if (obj is null) return false;
return this.GetHashCode().Equals(obj.GetHashCode());
}
}
您想使用哈希集作为键。
所以键是引用,其中一个键是一个哈希集引用。
ContainsKey 比较引用。
对于您想做的事情,您可以创建一个 class 实现 IEqualityComparer 以将其传递给字典构造函数。
https://docs.microsoft.com/dotnet/api/system.collections.generic.iequalitycomparer-1
如果你想要一个完整的管理,你应该创建一个新的 class 嵌入字典并实现你自己的 public 包装字典的操作:ContainsKey 和你需要的所有其他方法。
public class MyDictionary : IEnumerable<>
{
private Dictionary<HashSet<Vector3>, Vector3> d
= new Dictionary<HashSet<Vector3>, Vector3>();
public int Count { get; }
public this...
public ContainsKey()
{
// implements your own comparison algorithm
}
public Add();
public Remove();
...
}
因此您将拥有一个适合您预期用途的强类型字典。
我正在检查一组边是否已经包含 2 个点之间的连接。
我想使用包含 2 个向量的 HashSet
作为 Dictionary
键。然后我希望能够调用一个性能Dictionary.ContainsKey(hashSet)
。我希望 contains/equality 检查依赖于集合中的向量。
费。如果我将 HashSet [V000 V001]
添加到字典中。我想让 Dictionary.ContainsKey(HashSet [V001 V000])
return 为真。 (HashSet,所以顺序可以不同,只是元素相同)
问题似乎是,Dictionary.ContainsKey()
方法确实将单独创建的 HashSets
视为不同的对象,尽管它们包含相同的元素。
Dictionary<HashSet<Vector3>, Vector3> d = new Dictionary<HashSet<Vector3>, Vector3>();
HashSet<Vector3> s = new HashSet<Vector3>();
s.Add(Vector3.one);
s.Add(Vector3.zero);
d.Add(s);
HashSet<Vector3> s2 = new HashSet<Vector3>();
s2.Add(Vector3.zero);
s2.Add(Vector3.one);
bool doesContain = d.ContainsKey(s2); // should be true
您还可以建议一种更好的方法来执行此操作'Contains()' 高效检查。
HashSet
类型不执行您想要开箱即用的相等比较。它仅具有引用相等性。
要获得您想要的内容,您需要一个新类型来用作字典键。新类型将有一个 HashSet 属性,并重载 Equals()
和 GetHashCode()
,此时也可以实现 IEquatable
。
我会帮你入门的:
public class HashKey<T> : IEquatable<HashKey<T>>
{
private HashSet<T> _items;
public HashSet<T> Items
{
get {return _items;}
private set {_items = value;}
}
public HashKey()
{
_items = new HashSet<T>();
}
public HashKey(HashSet<T> initialSet)
{
_items = initialSet ?? new HashSet();
}
public override int GetHashCode()
{
// I'm leaving this for you to do
}
public override bool Equals(Object obj)
{
if (! (obj is HashKey)) return false;
return this.GetHashCode().Equals(obj.GetHashCode());
}
public bool Equals(HashSet<T> obj)
{
if (obj is null) return false;
return this.GetHashCode().Equals(obj.GetHashCode());
}
}
您想使用哈希集作为键。
所以键是引用,其中一个键是一个哈希集引用。
ContainsKey 比较引用。
对于您想做的事情,您可以创建一个 class 实现 IEqualityComparer 以将其传递给字典构造函数。
https://docs.microsoft.com/dotnet/api/system.collections.generic.iequalitycomparer-1
如果你想要一个完整的管理,你应该创建一个新的 class 嵌入字典并实现你自己的 public 包装字典的操作:ContainsKey 和你需要的所有其他方法。
public class MyDictionary : IEnumerable<>
{
private Dictionary<HashSet<Vector3>, Vector3> d
= new Dictionary<HashSet<Vector3>, Vector3>();
public int Count { get; }
public this...
public ContainsKey()
{
// implements your own comparison algorithm
}
public Add();
public Remove();
...
}
因此您将拥有一个适合您预期用途的强类型字典。