将实例的一个属性与其他实例的数组进行比较

时间:2013-02-15 20:43:48

标签: objective-c cocoa comparison

我正在尝试为Card类编写实例方法,将单个卡与数组进行比较。该类有一些属性,如:shapecolorotherCards数组中包含此类的其他实例,这些实例也包含shapecolor s。

现在,我想编写一个可以分别检查所有这些属性的方法。如何传递特定属性,如:[allAttributesIsEqual:otherCards compareWith: self.shape]?所以我可以在实际比较时传递self.shapeself.color

- (BOOL)allAttributesIsEqual: (NSArray *)otherCards
{
    //self.shape is equal to othercards.shape
}

2 个答案:

答案 0 :(得分:3)

您不能只传入self.shape,因为这会为您提供该属性的。但是,感谢一些Cocoa / ObjC的炸药,你可以传递一个属性(或方法)的 name 并稍后得到结果。

聪明(我敢说,甚至可能是“Pythonic”)方式:

// The name of the property we're interested in.
NSString * key = @"color";
// Get the values of that property for all the Cards in the array, then
// collapse duplicates, because they'll give the same results when comparing
// with the single card.
NSSet * vals = [NSSet setWithArray:[arrayOfCards valueForKey:key]];
// Now, if the set has only one member, and this member is the same
// as the appropriate value of the card we already have, all objects
// in the array have the same value for the property we're looking at.
BOOL colorIsEqual = ([vals count] == 1 && [vals containsObject:[myCard valueForKey:key]]);

然后您的方法可能如下所示:

- (BOOL)allOtherCards: (NSArray *)otherCards haveEqualAttribute: (NSString *)key;
然而,Dan F建议对你感兴趣的每个房产实施- (BOOL)<#property#>Equal: (NSArray *)otherCards;并不是一个坏主意。当然,每一个都可以调用基础“聪明”的版本。

答案 1 :(得分:2)

这个想法是你(作为Card类)知道两个实例“相等”意味着什么。听起来在你的情况下,如果它们的颜色和形状属性匹配,则两张卡是等效的。首先在您的自定义Card类上实施-isEqual:(以及-hash)。这是让对象暴露其是否与其他对象相同的概念的标准方法。您可以根据需要实施此操作。在此isEqual方法中,您可以检查所有相关属性:

- (BOOL)isEqual:(id)otherObject
{
    if (![otherObject isKindOfClass:[self class]) {
        return NO;
    }
    Card * otherCard = (Card *)otherObject;
    // now compare the attributes that contribute to "equality"
    return ([self.shape isEqual:otherCard.shape] && [self.color isEqual:otherCard.color]);
}

现在,一旦您的自定义对象支持此-isEqual:,您就可以检查阵列中的所有卡片,看看是否有任何卡片等于候选卡片。您可以自己完成循环并使用-isEqual:,但是以系统标准方式执行此操作的好处是您还可以使用系统提供的便捷方法来检查集合成员资格,例如:

if ([myCardList containsObject:candidateCard]) {
    // one of the cards compared as "equal"
}

如果您希望按照课程中的方法请求执行此操作,则可以按照以下方式对其进行构造:

- (BOOL)isRepresentedInArray:(NSArray *)arr
{
    return [arr containsObject:self];
}