按位置获取 HashSet<T> 的元素

6
有没有办法从 HashSet 中获取第三行?例如
HashSet<string> ContinuedForums = new HashSet<string>();
ContinuedForums.add("a");
ContinuedForums.add("b");
string hellow = ContinuedForums[1];

是的,我想使用 HashSet


当然。枚举并获取前两个,然后丢弃它们。然后获取第三个并退出循环。这也可以使用Linq .Skip(2).First()来完成。如果您想要更好的方法,请使用更好的工具。还请注意,枚举顺序和插入顺序不能保证匹配。 - Anthony Pegram
var value = ContinuedForums.ToList()[2]; :) - ctrlplusb
以前的注释更有效率! - ctrlplusb
2
这看起来对数据结构的使用有误。 - NickD
2
按照什么标准确定"第三个"?是指添加的第三个吗?还是按排序后的值来确定第三个?在 HashSet 中,“第三个”没有实际意义。 - hatchet - done with SOverflow
显示剩余4条评论
4个回答

16

HashSet<T> 是一种无序的集合。

你可以通过 ContinuedForums.Skip(2).First() 获取第三个元素,但这不一定是你添加的“第三个”元素,并且随着添加或删除元素,其顺序会改变。

如果你需要保留顺序,则 HashSet<T> 可能不是正确的集合类型。它不旨在保留顺序或通过索引访问。


+1. 或许可以使用OrderedDictionary作为数据结构。 - Alexei Levenkov
@AlexeiLevenkov 或许可以使用 HashSet + List 等数据结构。 - Reed Copsey

4

如果你想在性能和顺序之间取得平衡,最好的方法是保留两种数据结构:HashSet<T> 可以实现 O(1) 的查找,List<T> 则用于枚举(或快速进行索引访问)。


1
如果您在谈论“第三个”是指添加的第三个元素,那么没有办法。HashSet不会公开这些信息。这是HashSet内部实现的未记录副作用,如果您将这些字符串添加到HashSet中:“one”,“two”,“three”,则枚举其内容时将按照添加顺序返回相同的内容。但由于这是未记录的行为,编写依赖于该行为的代码将是一个大错误。原因是HashSet的未来版本可能会以完全不同的方式运行。还要注意,如果您从HashSet中删除“two”,然后添加“four”,则枚举HashSet很可能会返回“one”,“four”,“three”。
“位置”的整个概念是HashSet的内部实现细节。它在其方法和属性中不公开任何有关位置提供信息的承诺。因此,就HashSet用户而言,位置的概念不存在。

1

如果集合中的顺序很重要,您可以使用SortedSet

这不会按照您添加它们的顺序给您项目,而是对它们进行排序。


MSDN链接经常失效。然而,链接的内容并没有比这里的文本更好地回答问题。@FoundWaldoException:在你推荐的库中包含一个能够满足OP需求的代码示例将是一个很好的答案。 - jpaugh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接