比较objective-c中的数组

12 arrays cocoa compare objective-c

好的一个非常简单的问题..在c ++中似乎有用但在Objective-c中我似乎很难用它:S ..如果你想比较两个数组它应该是这样的东西吧

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

究竟是什么问题?

Pet*_*sey 41

这些是Cocoa数组对象(NSArray的实例),而不是C数组或C++向量,并且请记住Objective-C没有运算符重载.您可以对对象执行的唯一操作是将其传递,将其存储在变量中,然后向其发送消息.

所以array-subscript运算符与Objective-C对象有关.我不认为取消引用指向Objective-C对象的指针在语义上是有效的,所以这段代码应该给你一个编译器错误.不过,我可能会记错了.如果它确实进入运行时,那么代码迟早会崩溃,因为你正在访问超出数组对象末尾的内存.

(2013年的编辑:Objective-C现在支持对象的下标.这最终转化为适当的objectAtIndex:replaceObjectAtIndex:withObject:消息.所以,问题中的代码现在实际上可以工作,虽然它仍然不是简单地走一个数组的正确方法,比较两个数组要少得多.)

通过索引从NSArray对象检索对象的正确方法是不使用array-subscript运算符,而是向数组对象发送objectAtIndex:消息:

[myArray objectAtIndex:i]
Run Code Online (Sandbox Code Playgroud)

迭代数组对象元素的正确方法,假设你真的不需要其他东西的索引(比如替换可变数组中的对象),就是直接循环它(这叫做"快速枚举") ):

for (MyObject *myObject in myArray) {
    …
}
Run Code Online (Sandbox Code Playgroud)

NSArray也响应objectEnumeratorreverseObjectEnumerator,它返回一个类似可迭代的对象.在这两者中,reverseObjectEnumerator在新代码中更有用,因为您可以直接迭代数组以向前迭代.在存在快速枚举之前,它们都是最有用的; 代码看起来像这样:

NSEnumerator *myArrayEnum = [myArray objectEnumerator];
MyObject *myObject;
while ((myObject = [myArrayEnum nextObject])) {
    …
}
Run Code Online (Sandbox Code Playgroud)

(是的,这是条件中的一项任务.故意,因此额外().我们当时大胆编码,不是吗?)

但是,正如你正在做的那样,你更可能想要向其中一个数组发送一条isEqualToArray:消息,正如Williham Totland所说:

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];
Run Code Online (Sandbox Code Playgroud)

这将确保两个数组具有相同的长度,然后以锁步方式将它们两者一起移动,发送isEqual:到每对对象.YES如果每条isEqual:消息都返回YES,它将返回; NO除此以外.数组可能包含不同的对象,但只要每对相等,数组本身就是相等的.

这假设你想要对象平等.如果其中一个对象YES在您发送isEqual:消息并传递另一个对象时响应,则它们是相同的.如果您想比较对象的身份,那么您需要自己执行锁步循环并使用==:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但那不太可能.大多数时候,我想测试对象的平等,而不是身份,所以isEqualToArray:我想要的.

  • @nmr:"在所有`isEqualTo <Type>:`Cocoa框架的方法中,`nil`不是一个有效的参数,这些方法的实现可能会在收到`nil`时引发异常.但是,为了向后兼容,Cocoa框架的`isEqual:`方法接受`nil`,返回`NO`." (2认同)

Wil*_*and 19

你想要这个isEqualToArray:方法.如:

if ([arrayOne isEqualToArray:arrayTwo]) {
  // Do something
}
Run Code Online (Sandbox Code Playgroud)

这将递归地比较两个阵列,同时具有不必要的迂回且不需要循环的优点.