减去 HashSets(并返回一个副本)?
我有一个 HashSet,
var universe = new HashSet<int>();
和一堆子集,
var sets = new List<HashSet<int>>(numSets);
我想减去一个块,我可以这样做:
var remaining = universe.ExceptWith(sets[0]);
但是 ExceptWith
可以就地工作。我不想修改宇宙
。我应该先克隆它,还是有更好的方法?
I've got a HashSet,
var universe = new HashSet<int>();
And a bunch of subsets,
var sets = new List<HashSet<int>>(numSets);
I want to subtract a chunk, which I can do like this:
var remaining = universe.ExceptWith(sets[0]);
But ExceptWith
works in-place. I don't want to modify the universe
. Should I clone it first, or is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不像
Except
扩展方法那么简单,但可能更快(您应该运行一些性能测试来确保)Not as simple as with the
Except
extension method, but probably faster (you should run a few performance tests to make sure)Except()
怎么样?How about
Except()
?我针对克隆和使用 HashSet 原生函数
ExceptWith
对 Linq 的Except
方法进行了基准测试。这是结果。http://programanddesign.com/cs/subtracting-sets/
I benchmarked Linq's
Except
method against cloning and using the HashSet-native functionExceptWith
. Here are the results.http://programanddesign.com/cs/subtracting-sets/
哈希集必须跟踪其哈希算法常量及其溢出箱。集合中的元素通过引用保存。正如 Thomas Levesque 所建议的那样,使用复制构造函数创建新的哈希会创建此开销的浅表副本,并且速度应该相当快。按照 James McNellis 建议的方式使用 except() 首先创建一个匿名副本,然后将其传递给复制构造函数,该复制构造函数使用匿名中的字段来初始化自己的字段。正如托马斯所说,你可能会做一些性能测试,但理论上他的答案应该击败詹姆斯的答案。顺便说一句,按照我的思维方式,浅拷贝不是克隆,因为我相信克隆意味着底层元素也被复制。具有共同元素的哈希集使用修改时复制策略。
A hash set has to track its hash algorithm constants, and its overflow bins. The elements in the set are held by reference. Creating a new hash with the copy constructor, as Thomas Levesque suggests, creates a shallow copy of this overhead and should be quite fast. Using Except() in the way that James McNellis suggests first creates an anonymous copy and then passes that to the copy constructor which uses the fields in the anonymous to initialize its own fields. As Thomas said, you might do a few performance tests, but theoretically his answer should beat James' answer. And by the way, to my way of thinking, a shallow copy is not a clone since I believe a clone implies that the underlying elements are also copied. Hash sets with common elements use a copy when modified strategy.
答案很晚,但有时可能有用。
@mpen 通过使用 Linq 的 except(IEnumerable<>) 来回答,
这使得 linq 循环通过 IEnumerable 检查它是否包含。
怎么样
Very late answer but maybe useful sometimes.
@mpen answered by using Linq's Except(IEnumerable<>)
Which make linq loop trough IEnumerable check if it's contains.
How about
显然,在某些情况下,“手动”在循环中添加项目比复制整个集合然后删除项目更有效。我能想到的一个...
Obviously in a few cases 'manually' adding items in a loop is more efficient than copying the whole set and then removing items. One I can think of ...