13

非常に簡単な質問です。c++では機能するようですが、Objective-cでは苦労しているようです:S .. 2つの配列を比較する場合は、次のようになります。

for ( int i = 0; i < [appdelegate.nicearray count]; i++ ) 
{ 
  if ( appdelegate.nicearray[i] == appdelegate.exercarray[i] )
  { 
     NSLog(@"the same elements in this selection");
  }
}

正確には何が問題なのですか?

4

5 に答える 5

44

これらはCocoa配列オブジェクト(NSArrayのインスタンス)であり、C配列やC ++ベクトルではありません。また、Objective-Cには演算子のオーバーロードがないことに注意してください。オブジェクトでできることは、オブジェクトを渡し、変数に格納し、メッセージを送信することだけです。

そのため、Array-subscript演算子はObjective-Cオブジェクトでは間違っています。Objective-Cオブジェクトへのポインターを逆参照することは言語的にも有効ではないと思うので、このコードはコンパイラエラーを与えるはずです。しかし、私は覚えていないかもしれません。実行時に到達した場合、配列オブジェクトの終わりを超えてメモリにアクセスしているため、遅かれ早かれそのコードはクラッシュします。

objectAtIndex:(2013年からの編集:Objective-Cはオブジェクトの添え字をサポートするようになりました。これは最終的に適切なメッセージに変換されreplaceObjectAtIndex:withObject:ます。したがって、質問のコードは実際に機能しますが、配列を単純にウォークする適切な方法ではありませんが、 2つのアレイを比較することははるかに少ないです。)

NSArrayオブジェクトからそのインデックスによってオブジェクトを取得する適切な方法は、array-subscript演算子を使用するのではなく、配列オブジェクトに次のobjectAtIndex:メッセージを送信することです。

[myArray objectAtIndex:i]

配列オブジェクトの要素を反復処理する適切な方法は、他の何か(可変配列内のオブジェクトの置換など)のインデックスが実際には必要ない場合、直接ループすることです(これは「高速列挙」と呼ばれます)。 )::

for (MyObject *myObject in myArray) {
    …
}

NSArrayは、objectEnumeratorreverseObjectEnumeratorにも応答します。これらは、同様に反復可能なオブジェクトを返します。2つのうち、reverseObjectEnumerator配列を直接反復して前方に反復できるため、新しいコードでより便利です。どちらも、高速列挙が存在する前に最も役立ちました。そのコードは次のようになりました。

NSEnumerator *myArrayEnum = [myArray objectEnumerator];
MyObject *myObject;
while ((myObject = [myArrayEnum nextObject])) {
    …
}

(はい、それは条件の割り当てです。意図的に、したがって余分()です。私たちは当時大胆にコーディングしましたね?)

isEqualToArray:ただし、 Williham Totlandが提案したように、実行していることについては、配列の1つにメッセージを送信する可能性が高くなります。

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];

これにより、両方の配列の長さが同じになり、両方をロックステップでウォークして、isEqual:オブジェクトの各ペアに送信します。YESすべてのisEqual:メッセージが返された場合に返されますYES; NOそうでなければ。配列には異なるオブジェクトが含まれる場合がありますが、各ペアが等しい限り、配列自体は等しくなります。

これは、オブジェクトの同等性が必要であることを前提としています。メッセージYESを送信してもう一方のオブジェクトを渡すときに一方が応答する場合、2つの別々のオブジェクトは等しくなります。isEqual:オブジェクトのIDを比較する場合は、自分でロックステップループを実行して、次を使用する必要があります==

BOOL arraysContainTheSameObjects = YES;
NSEnumerator *otherEnum = [otherArray objectEnumerator];
for (MyObject *myObject in myArray) {
    if (myObject != [otherEnum nextObject]) {
        //We have found a pair of two different objects.
        arraysContainTheSameObjects = NO;
        break;
    }
}

しかし、それはありそうにありません。ほとんどの場合、私はアイデンティティではなくオブジェクトの同等性をテストしたかったので、私が望んでいたのはそうisEqualToArray:です。

于 2009-07-16T15:26:24.083 に答える
24

isEqualToArray:メソッドが必要です。のように:

if ([arrayOne isEqualToArray:arrayTwo]) {
  // Do something
}

これにより、2つのアレイが再帰的に比較されますが、不必要に遠回りにならず、ループを必要としないという利点があります。

于 2009-07-16T14:10:26.230 に答える
1

このコードを実行したときに得られる結果を教えてください。アプローチは正しいですが、これを試してください:

for (int i =0; i< appdelegate.nicearray.count; i++)
{
    if ([[appdelegate objectAtIndex:i] isEqual: [appdelegate.exercarray objectAtIndex:i]])
    {
        NSLog(@"the same");
    }
}  
于 2009-07-16T14:10:06.370 に答える
1

これは、トップランクの例に基づいてまとめた小さなものです。これは、順序や重複があるかどうかに関係なく、配列に同じ値が含まれていることを確認するだけです。私は主にこれを使用して、2つの辞書(多くの場合、さまざまな並べ替え順序でallKeys配列を返す)のキーを比較して、同じオブジェクトが含まれているかどうかを確認します。私がこれを採用した例を提供してくれたPeterHosleyに感謝します。

#pragma mark - Arrays
// Check to see if arrays contain the same elements, not necessarily in the same order
// This is different from [array isEqualToArray:responseKeys] which demands the same order in both arrays
// ## Does not compensate for duplicate entries in an array
+ (BOOL)doArraysContainTheSameObjects:(NSArray *)firstArray withArray:(NSArray *)secondArray {
    BOOL arraysContainTheSameObjects = YES;

    for (id myObject in firstArray) {
        if (![secondArray containsObject:myObject]) {
            // We have found an object that is not in the other array.
            arraysContainTheSameObjects = NO;
            break;
        }
    }
    return arraysContainTheSameObjects;
}
于 2015-02-11T21:30:53.850 に答える
0

配列を比較するときは、次のようにします。

  • 他の配列がnilでないときに、いずれかの配列がnilであるかどうかを確認します
  • 長さが同じかどうかを確認してください
  • 他の配列の一致する要素をチェックして、各要素を繰り返します(forループを使用します)。

要素を比較するには、「等しい」と見なしたいものを定義する必要があります。配列内のポインターが等しい場合にのみ等しいのか、コンテンツも等しい場合に等しいのか。

ポインタの場合は、==を使用できます。

詳細な比較には、CompareToなどを使用する必要がある場合があります。

于 2009-07-16T14:11:19.163 に答える