2009-07-16 5 views
8

좋아, 아주 간단한 질문 .. C++에서 작동하는 것처럼 보이지만 객관적으로 - 나는 그것을 고민하는 것 같다. : 두 배열을 비교하려면 다음과 같이해야한다. 이 권리objective-c 배열을 비교

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

정확히 무엇이 문제입니까?

답변

35

이들은 C 배열 또는 C++ 벡터가 아닌 Cocoa 배열 개체 (NSArray의 인스턴스)이며 Objective-C에는 연산자 오버로드가 없음을 기억하십시오. 개체로 수행 할 수있는 유일한 작업은 변수를 전달하고 변수에 저장 한 다음 메시지를 보내는 것입니다.

따라서 배열 - 아래 첨자 연산자는 Objective-C 객체에 잘못되었습니다. Objective-C 객체에 대한 포인터를 역 참조하는 것이 언어 적으로 유효하다고 생각하지 않습니다. 따라서이 코드는 컴파일러 오류를 제공해야합니다. 그래도 나는 잘못 생각할지도 모른다. 런타임으로 만들면 조만간 배열 오브젝트의 끝을 넘어 메모리에 액세스하므로 코드가 조만간 충돌합니다.

(2013 년부터 편집 : Objective-C는 이제 객체의 첨자를 지원합니다.) 궁극적으로 적절한 objectAtIndex: 또는 replaceObjectAtIndex:withObject: 메시지로 변환됩니다. 그래도 문제의 코드는 실제로 작동하지만 아직 올바른 방법은 아닙니다. 단순히 배열을 걸 으면 훨씬 적은 두 배열을 비교할 수 있습니다.

[myArray objectAtIndex:i] 

적절한 방식 :)

색인하여 NSArray를 개체에서 객체를 검색하는 적절한 방법은 배열 첨자 연산자를 사용하는 것이 아니라 어레이의 objectAtIndex: 메시지 오브젝트 보내 아니다 배열 객체의 요소를 반복 할 때 (가변 배열의 객체를 대체하는 것과 같이) 다른 것을위한 색인이 필요 없다고 가정하면 직접 루프하는 것입니다 ("빠른 열거"라고 함) :

for (MyObject *myObject in myArray) { 
    … 
} 

NSArray도 응답합니다. s를 objectEnumeratorreverseObjectEnumerator으로 변경하여 유사한 반복 가능한 객체를 반환합니다. 이 두 가지 중에서 reverseObjectEnumerator은 새 코드에서 더 유용합니다. 배열에서 직접 반복하여 앞으로 반복 할 수 있기 때문입니다. 빠른 열거 형이 존재하기 전에 둘 다 가장 유용했습니다. 그 코드는 다음과 같이 보았다 :

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

(예, 그 조건에 할당의 고의적 따라서 추가 () 우리는, 당시 대담하게 코딩 우리를하지 않았다..?) 당신이 무엇을 위해

' 하고 재 Williham Totland 제안으로,하지만 당신은 더 많은 가능성이 배열 중 하나에게 isEqualToArray: 메시지를 보낼 :

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray]; 

이 두 배열 한 다음, 같은 길이가 잠금 단계에서 둘 다 걸어 확인한다 , isEqual:에게 개체의 각 쌍. 모든 isEqual: 메시지가 반환 된 경우 YES을 반환합니다. YES; 그렇지 않으면 NO입니다. 배열에는 다른 객체가 포함될 수 있지만 각 쌍이 동일하면 배열 자체가 동일합니다.

개체 평등을 원한다고 가정합니다. 두 개의 개별 오브젝트는 메시지를 보내고 다른 오브젝트를 전달할 때 그 중 하나가 YES으로 응답하면 동등합니다. 당신이 개체의 ID를 비교하는 의미 경우에, 당신은 잠금 단계 루프를 직접 할 필요 ==를 사용합니까 :

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:은 제가 원했던 것입니다.

+11

+1 사람에게 물고기를 가르치기 위해 +1. – willc2

+0

임의의 후속 질문 :'[nsArrrayInstance isEqual : otherInstance]'는 [nsArrrayInstance isEqualToArray : otherInstance]'와 동일합니까? – nmr

+1

@nmr : 거의. 두 경우의 차이점은 다음과 같습니다. http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/FrameworkImpl.html#//apple_ref/doc/uid/20001286-1007347 http :// /developer.apple.CocoaObjects/CocoaObjects/CocoaObjects.html # // apple_ref/doc/uid/TP40002974-CH4-SW61 –

1

이 코드를 실행할 때 얻은 결과를 알려주십시오. 접근 방법은 정확하지만 다음 중 하나를 시도하십시오.

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

일반적으로 포인터 평등이 아닌 'isEqual :'을 사용하여 객체를 비교해야합니다. – Chuck

+0

또한 윌리엄 토틀 랜드 (William Thotland)가 제안한 것처럼 isEqualToArray :를 사용하면됩니다. (배열 - 첨자 연산자 대신에'objectAtIndex :'를 사용해야한다고 지적하는 소품) –

19

isEqualToArray: 메소드를 원하십니까? 마찬가지로 :하지 불필요하게 우회되는 및 루프를 필요로하지 않는 장점을 가지면서

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

이 반복적으로, 두 배열을 비교합니다. 배열을 비교했을 때

0

나는 다음을 수행하십시오 배열 중 하나가 전무 경우, 다른 하나는 길이가 같은

  • 으로 반복하는 경우 (볼
  • 확인이없는 경우

    • 확인보고 같은 for 루프를 사용하여) 각 요소에 대해 다른 배열의 일치하는 요소를 검사합니다.

    요소를 비교하려면 "평등"이라고 생각하고 싶은 요소를 정의해야합니다. 배열의 포인터가 같거나 내용이 동일하면 같을 수있는 경우에만 동일합니까?

    포인터 케이스의 경우 ==를 사용할 수 있습니다.

    비교를 위해 CompareTo 또는 유사한 것을 사용해야 할 수도 있습니다.

  • 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; 
    } 
    
    +0

    솔직히 말해서 일반적인 용도로 사용하려면 첫 번째 배열에 두 번째 배열의 모든 객체가 포함되어 있는지 확인해야합니다. –

    +0

    또한 firstArray가 nil이고 두 번째 배열이 빈 배열 인 경우 위의 메서드는 true를 반환합니다. – IronMan