在objective-c中比较数组

在objective-c中比较数组,objective-c,arrays,cocoa,compare,Objective C,Arrays,Cocoa,Compare,好的,一个非常简单的问题。。在C++中,它似乎有效,但在Objto-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"

好的,一个非常简单的问题。。在C++中,它似乎有效,但在Objto-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");
  }
}
for(int i=0;i<[appdelegate.nicearray count];i++)
{ 
if(appdelegate.nicearray[i]==appdelegate.exercarray[i])
{ 
NSLog(“此选择中的相同元素”);
}
}

到底是什么问题

试着告诉我们运行此代码时得到的结果。该方法是正确的,但请尝试以下方法:

for (int i =0; i< appdelegate.nicearray.count; i++)
{
    if ([[appdelegate objectAtIndex:i] isEqual: [appdelegate.exercarray objectAtIndex:i]])
    {
        NSLog(@"the same");
    }
}  
for(int i=0;i
您需要
isEqualToArray:
方法。例如:

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

这将递归地比较两个数组,同时具有不必要迂回和不需要循环的优点。

比较数组时,我执行以下操作:

  • 检查其中一个数组是否为零,而另一个数组是否为零
  • 检查长度是否相同
  • 在每个元素上迭代(使用类似于您的for循环),检查另一个数组中的匹配元素
要比较元素,您需要定义您认为“相等”的内容。仅当数组中的指针相等时,它们是否相等;或者,如果内容也相等,它们是否可以相等

对于指针的情况,可以使用==


对于深度比较,您可能需要使用CuffReto或类似的东西。

< P>这些是COCONA数组对象(NSales实例),而不是C数组或C++向量,并且记住Objto-C没有操作符重载。您可以对对象执行的唯一操作是传递对象、将对象存储在变量中以及向对象发送消息

因此数组下标运算符对于Objective-C对象是错误的。我认为,从语言上来说,取消引用指向Objective-C对象的指针都是无效的,所以这段代码应该会给您一个编译器错误。不过,我可能记错了。如果它进入运行时,代码迟早会崩溃,因为您访问的内存超出了数组对象的末端

(从2013年开始编辑:Objective-C现在支持订阅对象。这最终转化为适当的
objectAtIndex:
replaceObjectAtIndex:withObject:
消息。因此,问题中的代码现在实际上可以工作了,尽管它仍然不是简单地遍历数组的正确方法,更不用说比较了两个阵列。)

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

[myArray objectAtIndex:i]
在数组对象的元素上迭代的正确方法是直接循环(这称为“快速枚举”):

NSArray还响应
objectEnumerator
reverseObjectEnumerator
,这两个函数返回一个类似的iterable对象。在这两个函数中,
reverseObjectEnumerator
在新代码中更有用,因为您可以直接在数组上迭代以向前迭代。在快速枚举退出之前,这两个函数都最有用sted;代码如下所示:

NSEnumerator *myArrayEnum = [myArray objectEnumerator];
MyObject *myObject;
while ((myObject = [myArrayEnum nextObject])) {
    …
}
(是的,这是条件中的一个赋值。故意的,因此额外的
()
。我们当时很大胆地编码,不是吗?)

不过,对于您正在执行的操作,您更可能希望向其中一个数组发送
isEqualToArray:
消息,正如Williham Totland所建议的:

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];
这将确保两个数组具有相同的长度,然后以锁步方式遍历它们,向每对对象发送
isEqual:
。如果每个
isEqual:
消息返回
YES
;否则
NO
,则返回
YES
。数组可能包含不同的对象,但只要每对对象相等,则返回
YES
数组本身是相等的

这假设您希望对象相等。当您向其中一个对象发送
isEqual:
消息并传递另一个对象时,如果其中一个对象响应
YES
,则两个单独的对象相等。如果您想要比较对象的标识,则您确实需要自己执行锁步循环并使用
=

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:
就是我想要的。

下面是我根据排名靠前的示例编写的一个小程序。这只是检查数组是否包含相同的值,而不考虑顺序,也不考虑是否有重复的值。我主要用于比较两个字典的键(通常以不同的排序顺序返回它们的allKeys数组),看看它们是否包含相同的对象。感谢Peter Hosley提供了我改编的示例

#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;
}

您通常应该将对象与
isEqual:
,而不是指针相等进行比较。此外,您可以使用
isEqualToArray:
,正如Williham Totland所建议的那样。(指出他应该使用
objectAtIndex:
而不是数组下标操作符的道具。)随机跟进问题:是
[NSARRAYInstance isEqual:otherInstance]
相当于
[NSARRAYInstance isEqualToArray:otherInstance]
?@nmr:差不多。有两种边缘情况的区别:因此,归结起来,第一个链接声明,
isEqualTo…
可能假设参数的类型正确~我不确定第二个链接讨论的是什么边缘情况。也许我可以麻烦你详细说明一下?@nmr:“在Cocoa框架的所有
isEqualTo:
方法中,
nil
不是有效参数,这些方法的实现可能在收到
时引发异常
#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;
}