13

好的,一个非常简单的问题..在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");
  }
}

究竟是什么问题?

4

5 回答 5

44

这些是 Cocoa 数组对象(NSArray 的实例),而不是 C 数组或 C++ 向量,请记住,Objective-C 没有运算符重载。你可以对一个对象做的唯一事情就是传递它,将它存储在变量中,并向它发送消息。

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

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

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

[myArray objectAtIndex:i]

迭代数组对象的元素的正确方法,假设您真的不需要其他东西的索引(例如替换可变数组中的对象),是直接循环它(这称为“快速枚举” ):

for (MyObject *myObject in myArray) {
    …
}

NSArray 也响应objectEnumeratorand reverseObjectEnumerator,它返回一个类似的可迭代对象。两者中,reverseObjectEnumerator在新代码中更有用,因为您可以直接迭代数组以向前迭代。在快速枚举存在之前,它们都是最有用的;该代码如下所示:

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

(是的,这是条件中的一个赋值。故意,因此额外的()。我们当时大胆地编码,不是吗?)

但是,对于您正在做的事情,您更可能希望向其中一个数组发送isEqualToArray:消息,正如 Williham Totland 建议的那样:

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];

这将确保两个数组具有相同的长度,然后以锁步方式遍历它们,发送isEqual:到每对对象。YES如果每条isEqual:消息都返回,它将返回YESNO否则。数组可能包含不同的对象,但只要每一对相等,数组本身就相等。

假设您想要对象相等。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;
    }
}

但这不太可能。大多数时候,我想测试对象的相等性,而不是身份,这isEqualToArray:就是我想要的。

于 2009-07-16T15:26:24.083 回答
24

你想要的isEqualToArray:方法。如:

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

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

于 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

这是我根据排名靠前的例子汇总的一个小例子。这只是检查数组是否包含相同的值,而不考虑顺序以及是否有任何重复。我主要使用它来比较两个字典的键(通常以各种排序顺序返回它们的 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;
}
于 2015-02-11T21:30:53.850 回答
0

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

  • 检查是否有任何一个数组为 nil 而另一个不是
  • 检查长度是否相同
  • 在每个元素上迭代(使用你拥有的 for 循环)检查另一个数组中的匹配元素。

要比较元素,您需要定义要视为“相等”的元素。它们是否仅在数组中的指针相等时才相等,或者如果内容也相等,它们是否也相等。

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

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

于 2009-07-16T14:11:19.163 回答