2009-07-16 7 views
8

में सरणी की तुलना करना ठीक है एक बहुत ही सरल सवाल .. सी ++ में यह काम करता प्रतीत होता है लेकिन उद्देश्य-सी में मैं इसके साथ संघर्ष कर रहा हूं: एस .. यदि आप दो सरणी की तुलना करना चाहते हैं तो यह कुछ ऐसा होना चाहिए यह सहीउद्देश्य-सी

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

वास्तव में समस्या क्या है?

उत्तर

35

ये कोको सरणी वस्तुएं (एनएसएआरएआरई के उदाहरण) हैं, सी सरणी या सी ++ वैक्टर नहीं, और याद रखें कि उद्देश्य-सी में ऑपरेटर ओवरलोडिंग नहीं है। किसी ऑब्जेक्ट के साथ आप केवल एक ही चीज कर सकते हैं, इसे चारों ओर पास कर सकते हैं, इसे चर में स्टोर कर सकते हैं, और इसे संदेश भेज सकते हैं।

तो सरणी-सबस्क्रिप्ट ऑपरेटर उद्देश्य-सी ऑब्जेक्ट्स के साथ गलत है। मुझे नहीं लगता कि यह ऑब्जेक्टिव-सी ऑब्जेक्ट को पॉइंटर को डिफरेंस करने के लिए भी भाषाई रूप से मान्य है, इसलिए यह कोड आपको एक कंपाइलर त्रुटि दे रहा है। हालांकि, मैं गलत हो सकता है। यदि यह रनटाइम पर बनाता है, तो वह कोड जल्द या बाद में क्रैश हो जाएगा, क्योंकि आप सरणी ऑब्जेक्ट्स के सिरों से परे स्मृति तक पहुंच रहे हैं।

(वर्ष 2013 से संपादित करें: ऑब्जेक्टिव-सी अब वस्तुओं के subscripting का समर्थन करता है अंततः यह उचित objectAtIndex: या replaceObjectAtIndex:withObject: संदेश में तब्दील हो तो, सवाल में कोड वास्तव में अब, काम करेगा हालांकि यह अभी भी उचित तरीके से नहीं है।। बस एक सरणी चलने के लिए, दो सरणी की तुलना करने के लिए बहुत कम।

[myArray objectAtIndex:i] 

उचित तरीके से करने के लिए:)

उचित तरीके से अपने सूचकांक से एक NSArray वस्तु से एक वस्तु पुनः प्राप्त करने के सरणी-सबस्क्रिप्ट ऑपरेटर का उपयोग करने के लिए नहीं है, लेकिन सरणी objectAtIndex: संदेश आपत्ति भेजने के लिए है किसी सरणी ऑब्जेक्ट के तत्वों पर पुनरावृत्ति करें, मान लीजिए कि आपको वास्तव में किसी अन्य चीज़ के लिए इंडेक्स की आवश्यकता नहीं है (जैसे कि एक म्यूटेबल सरणी में ऑब्जेक्ट्स को प्रतिस्थापित करना), इसे सीधे लूप करना है (इसे "तेज़ गणना" कहा जाता है):

for (MyObject *myObject in myArray) { 
    … 
} 

एनएसएआरएआरई भी प्रतिक्रिया एस objectEnumerator और reverseObjectEnumerator, जो एक समान-पुनरावृत्त वस्तु को वापस कर देता है। दो में से, reverseObjectEnumerator नए कोड में अधिक उपयोगी है, क्योंकि आप सरणी पर सीधे फिर से आगे बढ़ने के लिए पुन: सक्रिय कर सकते हैं। तेजी से गणना होने से पहले उनमें से दोनों सबसे उपयोगी थे; कि कोड इस तरह देखा:

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

(हाँ, उस स्थिति में एक काम है जानबूझकर, इसलिए अतिरिक्त () हम निर्भीकता कोडित वापस तो, हम ऐसा नहीं किया।।?)

तुम क्या के लिए ' फिर से कर रही है, हालांकि, आप अधिक होने की संभावना सरणियों में से एक एक isEqualToArray: संदेश भेजने के लिए, चाहते हैं के रूप में Williham Totland सुझाव:

BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray]; 

यह सुनिश्चित करें कि दोनों सरणियों, एक ही लंबाई है तो उन दोनों को लॉक-कदम में चलना कर देगा , isEqual: को भेजना वस्तुओं की प्रत्येक जोड़ी। यह YES वापस करेगा यदि प्रत्येक isEqual: संदेश YES लौटा दिया गया है; अन्यथा NO। सरणी में अलग-अलग वस्तुएं हो सकती हैं, लेकिन जब तक प्रत्येक जोड़ी बराबर होती है, तब तक सरणी बराबर होती है।

मानता है कि आप ऑब्जेक्ट समानता चाहते हैं। यदि आप इसे 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: जो मैं चाहता था।

+11

+1 किसी व्यक्ति को मछली को पढ़ाने के लिए +1। – willc2

+0

यादृच्छिक अनुवर्ती प्रश्न: '[nsArrrayInstance isEqual: अन्यInstance]' 'के बराबर है [nsArrrayInstance isEqualToArray: अन्यInstance]'? – nmr

+1

@ एनएमआर: लगभग। दो एज-केस अंतर हैं: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/FrameworkImpl.html#//apple_ref/doc/uid/20001286-1007347 http://developer.apple।कॉम/लाइब्रेरी/मैक/प्रलेखन/कोको/अवधारणात्मक/कोकोफंडैमेंटल/कोको ऑब्जेक्ट्स/कोकोऑब्जेक्ट्स.html # // apple_ref/डॉक्टर/यूआईडी/टीपी 40002974-सीएच 4-एसड 61 –

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

इसके अलावा, आप इसे करने के लिए 'isEqualToArray:' का उपयोग कर सकते हैं, जैसा कि विलीहम टोटलैंड ने सुझाव दिया था। (यह इंगित करने के लिए प्रॉप्स कि वह सरणी-सबस्क्रिप्ट ऑपरेटर के बजाय 'objectAtIndex:' का उपयोग करना चाहिए।) –

19

आप isEqualToArray: विधि चाहते हैं। में के रूप में:

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

यह रिकर्सिवली दो सरणियों की तुलना करेंगे, नहीं बेकार में घुमावदार जा रहा है और एक पाश की जरूरत नहीं का लाभ करते हुए।

0

मैं जब सरणियों की तुलना निम्न कार्य करें:

  • जांच करें कि सरणियों के किसी भी नहीं के बराबर हैं जब अन्य
  • जांच करें कि लंबाई एक ही
  • दोहराएं हैं देखने के लिए (नहीं है को देखने के लिए आपके जैसे लूप का उपयोग करना) प्रत्येक तत्व पर अन्य सरणी में मिलान तत्व की जांच करना।

उन तत्वों की तुलना करने के लिए जिन्हें आप "बराबर" मानना ​​चाहते हैं उसे परिभाषित करने के लिए आवश्यक है। क्या वे केवल तभी बराबर होते हैं जब सरणी में पॉइंटर्स बराबर होते हैं या यदि सामग्री बराबर होती है तो वे बराबर हो सकती हैं।

सूचक मामले के लिए, आप == का उपयोग कर सकते हैं।

गहरी तुलना के लिए आपको तुलनात्मक या कुछ समान उपयोग करने की आवश्यकता हो सकती है।

1

यहां शीर्ष स्थान पर आधारित एक छोटा सा उदाहरण है। यह केवल जांच करता है कि सरणी में वही मान होते हैं, चाहे आदेश के बावजूद और यदि कोई डुप्लिकेट है। मैं मुख्य रूप से दो शब्दकोशों की चाबियों की तुलना करने के लिए इसका उपयोग करता हूं (जो अक्सर विभिन्न ऑर्डर में अपने ऑलकेज़ सरणी लौटाते हैं) यह देखने के लिए कि क्या वे एक ही वस्तुएं हैं। उदाहरण देने के लिए पीटर होस्ले धन्यवाद मैंने इसे अनुकूलित किया।

#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

इसके अलावा यदि पहला आरा शून्य है और दूसरा सरणी एक खाली सरणी है तो उपर्युक्त विधि सही हो जाएगी। – IronMan