在 Objective-C 中比较数组

发布于 2024-07-26 23:26:46 字数 323 浏览 4 评论 0原文

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

到底问题是什么?

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

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

捎一片雪花 2024-08-02 23:26:46

这些是 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还响应objectEnumeratorreverseObjectEnumerator,它们返回一个类似的可迭代对象目的。 两者中,reverseObjectEnumerator 在新代码中更有用,因为您可以直接迭代数组来向前迭代。 在快速枚举出现之前,它们都是最有用的。 该代码如下所示:(

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

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

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

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];

这将确保两个数组具有相同的长度,然后以锁步方式遍历它们,发送isEqual: 到每对对象。 如果每个 isEqual: 消息都返回 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: 就是我想要的。

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.

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.

(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.)

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:

[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 objectEnumerator and reverseObjectEnumerator, which return a similarly-iterable object. Of the two, reverseObjectEnumerator is 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:

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:

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 YES if every isEqual: message returned YES; NO otherwise. The arrays may contain different objects, but as long as each pair is equal, the arrays themselves are equal.

That assumes you want object equality. Two separate objects are equal if one of them responds with YES when 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 ==:

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.

我ぃ本無心為│何有愛 2024-08-02 23:26:46

您需要 isEqualToArray: 方法。 如:

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

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

You want the isEqualToArray: method. As in:

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.

辞旧 2024-08-02 23:26:46

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

for (int i =0; i< appdelegate.nicearray.count; i++)
{
    if ([[appdelegate objectAtIndex:i] isEqual: [appdelegate.exercarray objectAtIndex:i]])
    {
        NSLog(@"the same");
    }
}  

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");
    }
}  
茶底世界 2024-08-02 23:26:46

这是我根据排名最高的示例整理的一个小例子。 这仅检查数组是否包含相同的值,无论顺序如何以及是否存在重复项。 我主要用它来比较两个字典的键(通常以不同的排序顺序返回它们的 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;
}

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.

#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;
}
脸赞 2024-08-02 23:26:46

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

  • 检查是否有任何一个数组为零,而另一个数组则不是 nil
  • 检查长度是否相同
  • 对每个元素进行迭代(使用像您一样的 for 循环),检查中的匹配元素另一个数组。

要比较元素,您需要定义您想要视为“相等”的元素。 仅当数组中的指针相等时它们才相等,还是当内容也相等时它们才相等。

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

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

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文