2

Card単一のカードを配列と比較するクラスのインスタンスメソッドを作成しようとしています。このクラスには、:shapeやのようないくつかのプロパティがありcolorます。otherCards配列は、このクラスの他のインスタンスで満たされています。これらのインスタンスにもsshapecolorsがあります。

ここで、これらすべての属性を個別にチェックできるメソッドを作成したいと思います。次のように、特定の属性を渡すにはどうすればよい[allAttributesIsEqual:otherCards compareWith: self.shape]ですか?だから私は渡すことができますself.shapeself.color、実際に比較するときに?

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

2 に答える 2

3

プロパティのself.shapeが得られるため、単に渡すことはできません。ただし、Cocoa / ObjCのダイナマイトのおかげで、プロパティ(またはメソッド)の名前を渡して、後で結果を取得できます。

賢い(あえて言うなら、おそらく「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;は、まったく悪い考えではありません。もちろん、これらのそれぞれは、基本の「賢い」バージョンを呼び出すことができます。

于 2013-02-15T21:03:49.093 に答える
2

アイデアは、(カードクラスとしての)2つのインスタンスが「等しい」とはどういう意味かを知っているということです。あなたの場合、色と形の特性が一致していれば、2枚のカードは同等のように聞こえます。カスタムカードクラスに-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];
}
于 2013-02-15T20:54:16.717 に答える