从HashSet获取原始值

时间:2015-08-07 07:36:59

标签: c# hashset

更新: 从.Net 4.7.2开始,HashSet.TryGetValue - docs可用  HashSet.TryGetValue - SO post

我对HashSet有疑问,因为它没有提供与TryGetValue中已知的Dictionary类似的任何方法。我需要这样的方法 - 传递元素在集合中查找,并从其集合中设置返回元素(找到时)。

旁注 - "为什么你需要集合中的元素,你已经有那个元素?"。不,我不是,平等和身份是两回事。

HashSet没有被封存,但是它的所有字段都是私有的,因此从中得出它是毫无意义的。我无法使用Dictionary,因为我需要SetEquals方法。我正在考虑抓取HashSet的源并添加所需的方法,但许可证不是真正的开源(我可以看,但我无法分发/修改)。我可以使用反射,但HashSet中的数组不是readonly,这意味着我无法在每个实例生命周期内绑定到这些字段。

我不想仅仅为单堂课使用完整的图书馆。

到目前为止,我遇到了LINQ SingleOrDefault。所以问题是如何解决这个问题 - HashSetTryGetValue

5 个答案:

答案 0 :(得分:4)

您可能应该从www.site.com/DC/citydata 切换到HashSet

SortedSet有一个简单的TryGetValue()

SortedSet

调用时,元素只需要在Comparer中使用的所有属性集。它返回在Set中找到的元素。

答案 1 :(得分:3)

我同意这是基本上缺失的东西。虽然它仅在极少数情况下有用,但我认为它们是罕见的重要案例 - 最值得注意的是,关键的规范化。

我现在只能想到一个建议,这真的是犯规。

您可以在创建IEqualityComparer<T>时指定自己的HashSet<T> - 因此请创建一个记住其执行的最后一次正(即真正返回)Equals比较的参数。然后,您可以调用Contains,并查看要求相等比较器进行比较的内容。

注意事项:

  • 这会不必要地保留引用,因此最终可能会阻止对象被垃圾回收
  • 您可能希望在每个线程的基础上执行此操作(如果您在初始化后获得了一个未经修改的集合,那么< em>读取多个线程,例如)
  • 假设HashSet<T>没有使用任何优化,例如&#34;如果引用相同,请不要咨询相等比较器&#34;
  • 从根本上讲,这是一次可怕的虐待

我一直试图在寻找十字路口方面考虑其他选择,但我还没有到达任何地方......

正如评论中所指出的那样,尽可能将其封装起来是值得的 - 我怀疑你只需要一组非常有限的操作,所以我要在你自己的班级中包装HashSet<T>暴露你真正需要的操作 - 这样你就可以清除&#34;缓存&#34;每次操作后,删除我上面的​​第一个异议。

对我来说,这仍然是一种可怕的虐待,但是......

正如其他人所建议的那样,另一种方法是使用Dictionary<TKey, TValue>并自己实施SetEquals。这很简单 - 再次,你想要将它封装在你自己的类型中。无论哪种方式,您都应该首先设计类型本身,然后使用HashSet<>Dictionary<,>作为实现细节来实现它。

答案 2 :(得分:2)

听起来像是在尝试使用错误的工具。没错,您可以使用HashSet保存一些内存,但在我看来,您正试图实现不同的目标:获取与表示相等的实际元素。 所以实际上它们是两个不同的元素。只有memento(唯一的表示)是相等的。

因此,您最好使用字典,将元素添加为 。所以你可以把它拿回来(相同),但你错过了SetEquals ....

我认为SetEquals在其实现中没有什么不同于顺序比较它的桶顺序中的两个HashSets并且在第一个不相等时失败。

所以你应该同样使用简单的SequenceEqual()(LINQ)比较两个Keys集合。

所以这个扩展方法可以做到

public static SetEqual<T,G>(this IDictionary<T,G> d, IDictionary<T,G> e)
{
    return d.Keys.SequenceEqual(e.Keys);
}

这应该有效,因为Dictionary基本上是具有关联值的HashSet。而且更适合你的问题。 (好的,为了正确,代码应该是Dictionary<>而不是IDictionary<>,因为关键顺序很重要)

如果你需要第二个参数IEnumerable<>,请尝试排序以获得定义的顺序(效率不高)。

答案 3 :(得分:1)

答案 4 :(得分:0)

希望不要盲目但我没有在任何地方看到这个答案。如果你想要字典TryGetValue,你可以偷它。

theHashset.ToDictionary(item => item.ID).TryGetValue(key, out value)

您需要的只是一个用于确定唯一键的快速lambda。