2010-09-30 11 views
87

से कोई ऑब्जेक्ट प्राप्त करना यदि आप ऑब्जेक्ट के साथ ऑब्जेक्ट नहीं प्राप्त कर सकते हैं एट इंडेक्स: एनएसएससेट से तो आप ऑब्जेक्ट्स को कैसे पुनर्प्राप्त करते हैं?किसी NSSet

उत्तर

131

सेट के लिए कई उपयोग मामले हैं। सदस्यता के परीक्षण के लिए आप enumerateObjectsUsingBlock या NSFastEnumeration के साथ containsObject पर कॉल कर सकते हैं, anyObject का उपयोग सदस्य (यादृच्छिक नहीं) प्राप्त करने के लिए करें, या इसे allObjects के साथ किसी सरणी (किसी विशेष क्रम में) में परिवर्तित करें।

एक सेट उपयुक्त है जब आप डुप्लीकेट नहीं चाहते हैं, ऑर्डर की परवाह नहीं करते हैं, और तेजी से सदस्यता परीक्षण चाहते हैं।

बुला allObjects जो सभी वस्तुओं का एक NSArray रिटर्न का प्रयास करें:

+7

आप सेट को 'सदस्य:' संदेश भेजकर संभावित डुप्लिकेट द्वारा ज्ञात ऑब्जेक्ट को भी देख सकते हैं। यदि यह 'शून्य 'लौटाता है, तो सेट में आपके द्वारा पारित किए गए ऑब्जेक्ट के बराबर ऑब्जेक्ट नहीं होता है; यदि यह ऑब्जेक्ट पॉइंटर लौटाता है, तो वह पॉइंटर जो लौटाता है वह पहले से सेट में ऑब्जेक्ट पर होता है। सेट में ऑब्जेक्ट्स को 'हैश' और 'isEqual: 'को लागू करना होगा। –

+0

@ पीटर होसे मुझे नहीं लगता कि 'हैश' _needs_ लागू किया जाना है; अगर आप ऐसा करते हैं तो यह बहुत तेज हो जाएगा। – fumoboy007

+2

@ fumoboy007: एक सेट में स्टोरेज के लिए या एक शब्दकोश में कुंजी के रूप में उपयोग के लिए, हाँ यह करता है। एनएसओब्जेक्ट प्रोटोकॉल में 'हैश' के प्रलेखन से: "यदि दो ऑब्जेक्ट बराबर हैं (जैसा कि' isEqual: 'विधि द्वारा निर्धारित किया गया है), उनके पास एक ही हैश मान होना चाहिए।" वर्तमान में, एनएसओब्जेक्ट के' हैश 'और 'isEqual के कार्यान्वयन : 'ऑब्जेक्ट की पहचान (पता) का उपयोग करें। यदि आप 'isEqual: 'को ओवरराइड करते हैं, तो आप उन ऑब्जेक्ट्स की संभावना स्थापित कर रहे हैं जो समान नहीं हैं लेकिन बराबर हैं, यदि आप' हैश 'को ओवरराइड नहीं करते हैं, तो अभी भी अलग-अलग हैंश होंगे। यह उस आवश्यकता का उल्लंघन करता है जो बराबर वस्तुओं के बराबर हैश है। –

29

NSSet एक विधि objectAtIndex जरूरत नहीं है।

+0

क्या आपको कोई विचार है कि सरणी लौटाई गई है या नहीं? दूसरे शब्दों में, यदि मैं "setByAddingObject" का उपयोग करके सेट में ऑब्जेक्ट जोड़ रहा हूं, और मैंने "allObjects" का उपयोग किया है, तो हैं? ऑर्डर में आदेश दिया गया सरणी में तत्वों ने ऑब्जेक्ट्स को जोड़ा? – iosMentalist

+0

केवल परिणामी सरणी को NSSortPredicate के साथ सॉर्ट करें और आप ठीक होंगे – Jason

+0

यदि आप केवल एक विशिष्ट ऑब्जेक्ट में रूचि रखते हैं, तो फ़िल्टर किए गए SetUsingPredicate दृष्टिकोण का बेहतर उपयोग करें। – akw

6

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

तो, उदाहरण के लिए यदि आप एक डाटा मॉडल है कि एक आईडी मूल्य द्वारा उसकी विशिष्टता को परिभाषित करता है है (जैसे कि संपत्ति है:

@property NSUInteger objectID; 

तो आप को लागू होता isEqual:

- (BOOL)isEqual:(id)object 
{ 
    return (self.objectID == [object objectID]); 
} 

के रूप में और आप हैश को लागू कर सकता है: तो फिर

- (NSUInteger)hash 
{ 
return self.objectID; // to be honest, I just do what Apple tells me to here 
         // because I've forgotten how Sets are implemented under the hood 
} 

, तो आप उस आईडी के साथ एक वस्तु (और साथ ही के लिए चेक प्राप्त कर सकते हैं चाहे वह) के साथ NSSet में बताया गया है:

MyObject *testObject = [[MyObject alloc] init]; 
testObject.objectID = 5; // for example. 

// I presume your object has more properties which you don't need to set here 
// because it's objectID that defines uniqueness (see isEqual: above) 

MyObject *existingObject = [mySet member: testObject]; 

// now you've either got it or existingObject is nil 

लेकिन हाँ, एक NSSet बाहर कुछ पाने के लिए एक ही रास्ता जो पहली जगह में अपनी विशिष्टता को परिभाषित करता है कि पर विचार कर रहा है।

मैंने परीक्षण नहीं किया है कि तेजी से क्या है, लेकिन मैं गणना का उपयोग करने से बचता हूं क्योंकि सदस्य का उपयोग करते समय यह रैखिक हो सकता है: विधि बहुत तेज होगी। यह एनएसएआरएआरई के बजाय एनएसएससेट के उपयोग को प्राथमिकता देने के कारणों में से एक है।

12

NSArray *myArray = [myNSSet allObjects];

MyObject *object = [myArray objectAtIndex:(NSUInteger *)] 

अपने वांछित वस्तु के सूचकांक के साथ NSUInteger बदलें।

+1

होना चाहिए: MyObject * object = [myArray objectAtIndex: (NSUInteger *)] –

17

फ़िल्टर किए गए SetUsingPredicate का उपयोग करना संभव है यदि आपके पास आवश्यक वस्तु का चयन करने के लिए किसी प्रकार का अद्वितीय पहचानकर्ता है।

पहले विधेय बनाने (वस्तु में अपनी विशिष्ट आईडी संभालने "पहचानकर्ता" कहा जाता है और यह है एक NSString):

NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"identifier == %@", identifier]; 

और फिर विधेय का उपयोग कर वस्तु चुनें:

NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject; 
0
for (id currentElement in mySet) 
{ 
    // ** some actions with currentElement 
} 
4

Swift3 & iOS10 के लिए:

//your current set 
let mySet : NSSet 
//targetted index 
let index : Int 
//get object in set at index 
let object = mySet.allObjects[index] 
संबंधित मुद्दे

 संबंधित मुद्दे