NSMutableSet 包含重复项 [英] NSMutableSet contains Duplicates

查看:43
本文介绍了NSMutableSet 包含重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 card 的自定义类,我需要从一组随机大小的卡片中创建一组 10 张独特的卡片.此外,我需要先包含所有列入白名单的卡片,以确保它们始终包含在内.

I have a custom class called card and I need to create a set of 10 unique cards from an array of cards of a random size. Also, I need include any whitelisted cards first to make sure they are always included.

我的问题是来自白名单(并且只有白名单)的卡片可能在系列中重复.随机添加的卡片永远不会重复,并且计数始终正确(10).我不明白为什么 isEqual 有时似乎有效,但并非总是如此.

My problem is cards from the whitelist (and only the whitelist) are potentially duplicated in the set. The cards randomly added are never duplicated, and the count is always correct (10). I can't figure out why isEqual seems to work sometimes but not always.

这是我创建集合的地方(randoms 是要从中挑选的潜在卡片的数组):

Here is where I create the set (randoms is the array of potential cards to be picked from):

NSMutableSet *randomCards = [NSMutableSet setWithCapacity:10];

[randomCards addObjectsFromArray:whiteListArray];

while ([randomCards count] < 10) {
    NSNumber *randomNumber = [NSNumber numberWithInt:(arc4random() % [randoms count])];
    [randomCards addObject:[randoms objectAtIndex:[randomNumber intValue]]];
}

根据此处回答的另一个问题,我为我的 card 类覆盖了 isEqual 方法:

I overrode the isEqual method for my card class based on another question answered here:

- (BOOL)isEqual:(id)other {

if (other == self)
    return YES;
if (!other || ![other isKindOfClass:[self class]])
    return NO;
return [self isEqualToCard:other];

}

- (BOOL)isEqualToCard:(Card *)myCard {

if (self == myCard) {
    return YES;
}
if ([self cardName] != [myCard cardName] && ![(id)[self cardName] isEqual:[myCard cardName]])
    return NO;

return YES;
}

它似乎工作得很好,除非我添加了白名单卡片,我无法弄清楚我是如何得到重复的(但永远不会超过 2 个副本).

It seems to work perfectly except when I add in the whitelist cards, I can't figure out how I'm ending up with duplicates (but never more than 2 copies).

推荐答案

除了 isEqual 之外,您还需要覆盖 hash.

You need to override hash in addition to isEqual.

事实上,您总是需要确保这两种方法协同工作.来自 Apple 的文档:

In fact, you always need to make sure these two methods work together. From Apple's documentation:

如果两个对象相等(由 isEqual: 方法确定),则它们必须具有相同的哈希值.如果您在子类中定义哈希并打算将该子类的实例放入集合中,那么最后一点尤其重要.

If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection.

这样的事情应该可以工作:

Something like this should work:

- (NSUInteger)hash {
    return [[self cardName] hash];
}

这样,您的哈希取决于您用来进行比较的相同信息.

This way your hash depends on the same information that you're using to make the comparison.

NSMutableSet 等数据结构使用散列来快速将对象分组到不同的桶中.重要的是,如果两个对象相等,则它们具有相同的哈希值.(但是,如果两个对象具有相同的哈希值但不相等,那也没关系.因此您始终可以从 hash 返回相同的数字,但是您的性能将与使用数组相同.数据结构!)

The hash is used by data structures like NSMutableSet to quickly group objects into different buckets. It's important that if two objects are equal, they have the same hash value. (It's OK, however, if two objects have the same hash but are not equal. So you could always return the same number from hash, but then your performance would be the same as using an array. Data structures!)

这篇关于NSMutableSet 包含重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆