objective-c 比较objective-c中的数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1137839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
comparing arrays in objective-c
提问by Williham Totland
Ok a pretty simple question.. in c++ it seems to work but in objective-c i seem to struggle with it :S .. If you want to compare two arrays it should be something like this right
好的,一个非常简单的问题.. 在 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");
}
}
what's the problem exactly ?
究竟是什么问题?
回答by Peter Hosey
These are Cocoa array objects (instances of NSArray), not C arrays or C++ vectors, and remember that Objective-C does not have operator overloading. The only things you can do with an object are pass it around, store it in variables, and send messages to it.
这些是 Cocoa 数组对象(NSArray 的实例),而不是 C 数组或 C++ 向量,请记住,Objective-C 没有运算符重载。你可以对一个对象做的唯一事情就是传递它,将它存储在变量中,并向它发送消息。
So the array-subscript operator is wrong with Objective-C objects. I don't think it's even linguistically valid to dereference a pointer to an Objective-C object, so this code should be giving you a compiler error. I may be misremembering, though. If it does make it to runtime, that code will crash sooner or later, since you're accessing memory beyond the ends of the array objects.
所以数组下标运算符对于 Objective-C 对象是错误的。我不认为取消引用指向 Objective-C 对象的指针在语言上是有效的,所以这段代码应该给你一个编译器错误。不过我可能记错了。如果它确实进入运行时,该代码迟早会崩溃,因为您访问的内存超出了数组对象的末尾。
(EDIT from the year 2013: Objective-C now supports subscripting of objects. This ultimately translates into the appropriate objectAtIndex:or replaceObjectAtIndex:withObject:message. So, the code in the question would actually work now, although it's still not the proper way to simply walk an array, much less to compare two arrays.)
(从 2013 年开始编辑:Objective-C 现在支持对象的下标。这最终会转化为适当的objectAtIndex:或replaceObjectAtIndex:withObject:消息。因此,问题中的代码现在实际上可以工作,尽管它仍然不是简单地遍历数组的正确方法,更不用说比较两个数组了。)
The proper way to retrieve an object from an NSArray object by its index is not to use the array-subscript operator, but to send the array object the objectAtIndex:message:
通过索引从 NSArray 对象中检索对象的正确方法不是使用数组下标运算符,而是向数组对象发送objectAtIndex:消息:
[myArray objectAtIndex:i]
The proper way to iterate on the elements of an array object, assuming you don't really need the index for something else (such as replacing objects in a mutable array), is to loop on it directly (this is called “fast enumeration”):
迭代数组对象的元素的正确方法,假设你真的不需要其他东西的索引(例如替换可变数组中的对象),是直接循环它(这称为“快速枚举” ):
for (MyObject *myObject in myArray) {
…
}
NSArray also responds to objectEnumeratorand reverseObjectEnumerator, which return a similarly-iterable object. Of the two, reverseObjectEnumeratoris the more useful in new code, since you can just iterate on the array directly to iterate forward. Both of them were most useful before fast enumeration existed; that code looked like this:
NSArray 也响应objectEnumeratorand reverseObjectEnumerator,它返回一个类似的可迭代对象。两者中,reverseObjectEnumerator在新代码中更有用,因为您可以直接迭代数组以向前迭代。在快速枚举出现之前,它们都是最有用的。该代码如下所示:
NSEnumerator *myArrayEnum = [myArray objectEnumerator];
MyObject *myObject;
while ((myObject = [myArrayEnum nextObject])) {
…
}
(Yes, that's an assignment in the condition. Deliberately, hence the extra (). We coded boldly back then, didn't we?)
(是的,这是条件中的一个赋值。故意,因此额外的()。我们当时大胆地编码,不是吗?)
For what you're doing, though, you more likely want to send one of the arrays an isEqualToArray:message, as Williham Totland suggested:
但是,对于您正在做的事情,您更有可能希望向其中一个数组发送isEqualToArray:消息,正如 Williham Totland 所建议的:
BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];
This will make sure both arrays have the same length, then walk them both in lock-step, sending isEqual:to each pair of objects. It'll return YESif every isEqual:message returned YES; NOotherwise. The arrays may contain different objects, but as long as each pair is equal, the arrays themselves are equal.
这将确保两个数组具有相同的长度,然后以锁步方式遍历它们,发送isEqual:到每对对象。YES如果每条isEqual:消息都返回YES,它将返回;NO除此以外。数组可能包含不同的对象,但只要每对相等,数组本身就相等。
That assumes you want object equality. Two separate objects are equal if one of them responds with YESwhen you send it an isEqual:message and pass the other object. If you meant to compare the identities of the objects, then you do need to do the lock-step loop yourself and use ==:
这假设您想要对象相等。如果其中一个对象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;
}
}
But that's unlikely. Most of the time, I have wanted to test the objects' equality, not identities, so isEqualToArray:is what I wanted.
但这不太可能。大多数时候,我想测试对象的相等性,而不是身份,这isEqualToArray:也是我想要的。
回答by Williham Totland
You want the isEqualToArray:method. As in:
你想要isEqualToArray:方法。如:
if ([arrayOne isEqualToArray:arrayTwo]) {
// Do something
}
This will recursively compare the two arrays, while having the advantage of not being needlessly circuitous and not requiring a loop.
这将递归地比较两个数组,同时具有不需要不必要的迂回和不需要循环的优点。
回答by Dan Lorenc
Try telling us the result you're getting when you run this code. The approach is correct, but try this one:
尝试告诉我们您在运行此代码时得到的结果。方法是正确的,但试试这个:
for (int i =0; i< appdelegate.nicearray.count; i++)
{
if ([[appdelegate objectAtIndex:i] isEqual: [appdelegate.exercarray objectAtIndex:i]])
{
NSLog(@"the same");
}
}
回答by Alex Zavatone
Here's a little one I put together based on the top ranked example. This merely checks that the arrays contains the same values, irrespective of order and if there are any duplicates. I mainly use this to compare keys of two dictionaries (which often return their allKeys arrays in various sort orders) to see if they contain the same objects. Thanks Peter Hosley for providing the example I adapted this from.
这是我根据排名靠前的示例汇总的一个小示例。这只是检查数组是否包含相同的值,而不管顺序和是否有任何重复。我主要用它来比较两个字典的键(通常以各种排序顺序返回它们的 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;
}
回答by rein
I do the following when comparing arrays:
比较数组时,我执行以下操作:
- Check to see if any of the arrays are nil when the other is not
- Check to see if the lengths are the same
- Iterate (using a for loop like you have) over each element checking the matching element in the other array.
- 检查是否有任何数组为 nil,而另一个不是
- 检查长度是否相同
- 在每个元素上迭代(使用像你一样的 for 循环)检查另一个数组中的匹配元素。
To compare elements you need to define what you want to regard as being "equal". Are they equal only if the pointers in the array are equal or can they be equal if the content is equal too.
要比较元素,您需要定义要视为“相等”的内容。仅当数组中的指针相等时它们才相等,或者如果内容也相等,它们是否相等。
For the pointer case, you can use ==.
对于指针情况,您可以使用 ==。
For the deep comparison you might need to use CompareTo or something similar.
对于深度比较,您可能需要使用 CompareTo 或类似的东西。

