NSArray पर NSSet का उपयोग करना कब बेहतर है?


112

मैंने अपने ऐप्स में कई बार NSSets का उपयोग किया है, लेकिन मैंने कभी खुद को नहीं बनाया।

NSSetए के विपरीत एक का उपयोग करना बेहतर NSArrayक्यों है और क्यों?

जवाबों:


173

जब संग्रह में वस्तुओं का क्रम महत्वपूर्ण नहीं है, तो सेट संग्रह में आइटम खोजने के लिए बेहतर प्रदर्शन प्रदान करते हैं।

कारण यह है कि एक सेट वस्तुओं को खोजने के लिए हैश मूल्यों का उपयोग करता है (जैसे एक शब्दकोश) जबकि एक सरणी को किसी विशेष ऑब्जेक्ट को खोजने के लिए अपनी संपूर्ण सामग्री पर पुनरावृत्त करना पड़ता है।


9
log (1) vs log (n)
रोहन-पटल

25
@ रोहन-पटेल सही है ओ (1) बनाम ओ (एन)
मानसरोव रुसलान

1
यदि आदेश दिया गया है: बाइनरी खोज लागू होने के बाद से ओ (1) बनाम ओ (लोगन)। यदि अनियंत्रित है, तो O (1) बनाम O (n)
baskInEminence

180

Apple के डॉक्यूमेंटेशन से आई इमेज इसका बखूबी वर्णन करती है:

उद्देश्य-सी संग्रह

Arrayएक आदेश है (जब आप जोड़ते हैं तो ऑर्डर बनाए रखा जाता है) तत्वों का क्रम

[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];

[1, 2, 3, 4, 6, 4, 1, 2]

Setएक अलग (कोई डुप्लिकेट) नहीं है, तत्वों की अनियंत्रित सूची

[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];

[1, 2, 6, 4, 3]

2
अपने उदाहरण में, आप एक सरणी और एक सेट में आदिम जोड़ रहे हैं। न तो संभव है क्योंकि वे केवल वस्तुओं को शामिल कर सकते हैं।
FreeAsInBeer

10
आपके संपादन @Zaheer के लिए धन्यवाद, लेकिन यह वास्तव में अमान्य था। मैं आदिम नहीं जोड़ रहा था। मैं शाब्दिक अर्थ जोड़ रहा था।
जेम्स वेबस्टर

महान व्याख्या :) +1 :)
करुण

1
अपने स्पष्टीकरण से प्यार करें! +1 के लिए
विद्रोह

66

इसका सबसे अच्छा जवाब यह है कि यह एप्पल का अपना दस्तावेज है

यहां छवि विवरण दर्ज करें

मुख्य अंतर यह है कि NSArrayएक ऑर्डर किए गए संग्रह के लिए है और NSSetएक अनियोजित संग्रह के लिए है।

वहाँ कई लेख हैं जो दोनों के बीच गति के अंतर के बारे में बात करते हैं, जैसे यह एक । यदि आप एक अनियंत्रित संग्रह के माध्यम से पुनरावृत्ति कर रहे हैं, तो NSSetबहुत अच्छा है। हालांकि, कई मामलों में, आपको उन चीजों को करने की ज़रूरत है जो केवल कर NSArrayसकते हैं, इसलिए आप उन क्षमताओं के लिए गति का त्याग करते हैं।

NSSet

  • तुलना द्वारा मुख्य रूप से वस्तुओं तक पहुँच
  • अक्रमित
  • नकल नहीं होने देता

NSArray

  • अनुक्रमणिका द्वारा आइटम तक पहुँच सकते हैं
  • आदेश दिया
  • डुप्लिकेट की अनुमति देता है

यह सब वास्तव में वहाँ है! यदि इससे सहायता मिलती है तो मुझे बताएं।


NSSetअनुक्रमण के लिए आपको हमेशा बलिदान नहीं करना पड़ता है । समान डेटा के लिए दो अलग-अलग डेटा संरचनाओं का उपयोग करना आम है। या आप उस एरे पर निर्माण और इंडेक्स करते हैं :) लेकिन फिर एक डीबी का उपयोग करना बेहतर होता है, जिस पर इसे लागू किया गया है।
सुल्तान

"उस एरे पर एक इंडेक्स बनाएँ"। आप NSSet पर एक इंडेक्स नहीं बना सकते। कई अलग-अलग तकनीकें हैं जिनका आप उपयोग कर सकते हैं। और अगर आपको बीओटीएच मेमोरी और प्रोसेसिंग पावर में बलिदान करने की आवश्यकता है, तो आप इसे गलत कर रहे हैं।
सुल्तान

चूंकि प्रश्न के बारे में है NSSetऔर NSArray, मेरा उत्तर सटीक और पूर्ण है। हां, आप अन्य डेटा संरचनाओं का निर्माण कर सकते हैं, लेकिन मैं इन दोनों की तुलना कर रहा हूं।
13

मैंने त्याग किया लेकिन जब आप बलिदानों के बारे में बोलते हैं तो आपका उत्तर गलत है। यदि आपको कुछ कार्यक्षमता NSArrayऔर से कुछ फंक्शनलियोएलिटी की आवश्यकता है NSSet, तो सही उत्तर " NSArrayप्रदर्शन और बलिदान प्रदर्शन" नहीं है। उत्तर दोनों को मिलाते हैं या एक अलग डेटा संरचना का उपयोग करते हैं।
सुल्तान

मैंने कहा है कि मुख्य अंतर सेट अद्वितीय वस्तुओं के लिए है जहां एक सरणी में डुप्लिकेट हो सकते हैं। आदेश का पहलू उस तथ्य से गौण है।
मल्हल

12

NSOrderedSet iOS 5+ में उपलब्ध है ताकि मुख्य अंतर यह हो जाए कि आप डेटा संरचना में डुप्लिकेट ऑब्जेक्ट चाहते हैं या नहीं।


9

NSArray :

  1. डेटा का संग्रह का आदेश दिया
  2. डुप्लिकेट की अनुमति देता है
  3. यह संग्रह प्रकार वस्तु है

एनएसएसईटी :

  1. डेटा का अनियंत्रित संग्रह
  2. नकल नहीं होने देता
  3. यह संग्रह प्रकार की वस्तु भी है

7

एक सरणी का उपयोग उनके सूचकांक द्वारा वस्तुओं तक पहुंचने के लिए किया जाता है। किसी भी वस्तु को कई बार सरणी में डाला जा सकता है। उनके तत्वों के क्रम को व्यवस्थित करता है।

एक सेट का उपयोग मूल रूप से केवल यह जांचने के लिए किया जाता है कि आइटम संग्रह में है या नहीं। आइटम में ऑर्डर या इंडेक्सिंग की कोई अवधारणा नहीं है। आपके पास एक सेट में दो बार एक आइटम नहीं हो सकता है।

यदि कोई सरणी जाँचना चाहता है कि उसमें कोई तत्व है या नहीं, तो उसे अपने सभी आइटमों की जाँच करनी होगी। सेट तेजी से एल्गोरिदम का उपयोग करने के लिए डिज़ाइन किए गए हैं।

आप मूल्यों के बिना एक शब्दकोश की तरह एक सेट की कल्पना कर सकते हैं।

ध्यान दें कि सरणी और सेट केवल डेटा संरचना नहीं हैं। अन्य हैं, जैसे कतार, ढेर, ढेर, फाइबोनैचि का ढेर। मैं एल्गोरिदम और डेटा संरचनाओं के बारे में एक पुस्तक पढ़ने की सलाह दूंगा।

अधिक जानकारी के लिए विकिपीडिया देखें ।


दरअसल, एक सरणी को केवल उस बिंदु तक जांचने की आवश्यकता होती है जो आइटम पाया जाता है। यदि आइटम सरणी में IS है, तो बहुत कम ही हर आइटम को जांचने की आवश्यकता होगी।
FreeAsInBeer

हां, जैसा कि आप कहते हैं "यदि आइटम सरणी में आईएस है"। यदि आप यह उम्मीद करते हैं, तो आपको यह जाँचने की ज़रूरत नहीं है कि यह वहाँ है या नहीं। containsऑपरेशन की जटिलता है O(n)। सरणी में नहीं होने पर तुलना की संख्या n। सरणी में ऑब्जेक्ट होने पर तुलना की औसत संख्या n/2। भले ही ऑब्जेक्ट मिल जाए, लेकिन प्रदर्शन भयानक है।
सुल्तान

प्रदर्शन केवल एक बड़े सरणी के साथ भयानक होगा। अगर आपको पता था कि सरणी काफी बड़ी हो सकती है, तो ऐसे तरीके हैं जिनसे आप सरणी के प्रदर्शन में सुधार कर सकते हैं, जैसे कि सरणी का उपयोग करना।
FreeAsInBeer

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

जाहिर है कि एक अंतर होगा, मैं सिर्फ यह कह रहा हूं कि बड़ी ओ नोटेशन घातीय है; छोटे सरणियों के साथ, अंतर शून्य से कम होगा। इसके अलावा, NSArrays की गति पर अन्य लाभ हैं NSSet। हमेशा की तरह, यह एक व्यापार है।
FreeAsInBeer

5
NSArray *Arr;
NSSet *Nset;

Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];

NSLog(@"%@",Arr);
NSLog(@"%@",Nset);

सरणी

2015-12-04 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)

सेट

2015-12-04 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}


4

अन्य उत्तरों में मुख्य अंतर पहले ही दिए जा चुके हैं।

मैं बस यह ध्यान देना चाहूंगा कि जिस तरह से सेट और डिक्शनरी लागू की जाती है (यानी हैश का उपयोग करके), किसी को चाबियों के लिए परस्पर वस्तुओं का उपयोग न करने के लिए सावधान रहना चाहिए।

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

इससे कीड़े का पता लगाने में कुछ मुश्किल हो सकती है।


3

यहाँ आप NSArrayऔर NSSetडेटास्ट्रक्चर की पूरी तरह से तुलना कर सकते हैं ।

संक्षिप्त निष्कर्ष:

हां, NSArray NSSet से अधिक सरलता से धारण करने और पुनरावृत्ति करने के लिए तेज़ है। निर्माण के लिए कम से कम 50% तेज और पुनरावृति के लिए 500% से अधिक तेजी से। पाठ: यदि आपको केवल सामग्री पुनरावृति करने की आवश्यकता है, तो NSSet का उपयोग न करें।

बेशक, यदि आपको समावेशन के लिए परीक्षण करने की आवश्यकता है, तो NSArray से बचने के लिए कड़ी मेहनत करें। यहां तक ​​कि अगर आपको पुनरावृत्ति और समावेशन परीक्षण दोनों की आवश्यकता है, तो भी आपको शायद एक एनएसएसईटी चुनना चाहिए। यदि आपको अपने संग्रह को व्यवस्थित रखने और शामिल करने के लिए परीक्षण करने की आवश्यकता है, तो आपको दो संग्रह (एक NSArray और एक NSSet) रखने पर विचार करना चाहिए, जिनमें से प्रत्येक में समान वस्तुएं हों।

एनएसडबल NSMapTable की तुलना में निर्माण के लिए धीमा है - क्योंकि इसे प्रमुख डेटा की प्रतिलिपि बनाने की आवश्यकता है। यह लुकअप के लिए तेज़ होने से इसके लिए बनाता है। बेशक, दोनों के पास अलग-अलग क्षमताएं हैं इसलिए अधिकांश समय, यह निर्धारण अन्य कारकों पर किया जाना चाहिए।


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

2

आप आमतौर पर एक सेट का उपयोग करते हैं जब एक्सेस गति सार की होती है और ऑर्डर कोई फर्क नहीं पड़ता , या अन्य माध्यमों (एक विधेय या सॉर्ट डिस्क्रिप्टर के माध्यम से) द्वारा निर्धारित किया जाता है। उदाहरण के लिए कोर डेटा सेट का उपयोग करता है जब प्रबंधित वस्तुओं को कई-कई संबंधों के माध्यम से एक्सेस किया जाता है


1

बस इसे जोड़ने के लिए मैं कभी-कभी सेट का उपयोग करता हूं जैसे कि डुप्लिकेट को सरणी से हटाने के लिए: -

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.