একটি এনএসএসেট থেকে একটি বিষয় প্রাপ্ত করা


94

যদি আপনি অবজেক্টএটিআইএনডেক্সের সাথে কোনও জিনিস পেতে না পারেন: একটি এনএসএসেট থেকে তাহলে আপনি কীভাবে অবজেক্টগুলি পুনরুদ্ধার করবেন?


4
[[nsSetObjects allObjects] objectAtIndex: anyInteger]
মুবীন কাজী

উত্তর:


140

একটি সেট জন্য বেশ কয়েকটি ব্যবহারের কেস আছে। আপনি (যেমন enumerateObjectsUsingBlockবা NSFastEnumeration সহ) মাধ্যমে গণনা করতে containsObjectপারেন, সদস্যতার জন্য পরীক্ষা করার জন্য কল করতে পারেন, anyObjectসদস্য পেতে (এলোমেলো নয়) ব্যবহার করতে পারেন, বা এটিকে একটি অ্যারেতে (কোনও নির্দিষ্ট ক্রমে নয়) রূপান্তর করতে পারেন allObjects

যখন আপনি সদৃশ চান না, অর্ডারের বিষয়ে চিন্তা করেন না এবং দ্রুত সদস্যপদ পরীক্ষা করতে চান তখন একটি সেট উপযুক্ত।


7
আপনি কোনও সম্ভাব্য সদৃশ সেট দ্বারা একটি member:বার্তা প্রেরণ করে একটি পরিচিত বস্তুর সন্ধান করতে পারেন । যদি এটি ফিরে আসে nilতবে সেটটিতে আপনি যে পাস করেছেন তার সমান কোনও অবজেক্ট থাকে না; যদি এটি কোনও অবজেক্ট পয়েন্টারটি দেয়, তবে যে পয়েন্টারটি এটি ফিরে আসে সেটি সেটটিতে ইতিমধ্যে রয়েছে। সেট বস্তু বাস্তবায়ন করতে হবে hashএবং isEqual:এই জন্য উপযোগী হতে হবে।
পিটার হোসি

@PeterHosey আমি মনে করি না hash চাহিদা বাস্তবায়িত হবে; আপনি যদি এটি করেন তবে এটি কেবল অনেক দ্রুত যেতে পারে।
fumoboy007

4
@ fumoboy007: একটি সেট স্টোরেজ বা অভিধানে কী হিসাবে ব্যবহার করার জন্য, হ্যাঁ এটি করে। hashএনএসবজেক্ট প্রোটোকলের ডকুমেন্টেশন থেকে : "যদি দুটি বিষয় সমান হয় ( isEqual:পদ্ধতি অনুসারে নির্ধারিত হয় ), তাদের অবশ্যই হ্যাশ মান একই হতে হবে।" বর্তমানে, এনএসবজেক্টের প্রয়োগ hashএবং isEqual:অবজেক্টের পরিচয় (ঠিকানা) ব্যবহার করুন। আপনি যদি ওভাররাইড করে থাকেন তবে আপনি isEqual:এমন বস্তুগুলির সম্ভাবনা সেট করছেন যা অভিন্ন নয় তবে সমান — যা আপনি যদি ওভাররাইড না করেন hashতবে এখনও বিভিন্ন হ্যাশ থাকবে। এটি সমান বস্তুর সমান হ্যাশগুলির প্রয়োজনীয়তা লঙ্ঘন করে।
পিটার হোসে

4
@ fumoboy007: বিবেচনা কিভাবে হ্যাশ টেবিল কাজ করে: ধারক বাকেট কিছু সংখ্যা একটি অ্যারের আছে, এবং যা বালতি যে বস্তুর মধ্যে থাকা উচিত তা নির্ধারণ করতে প্রতিটি ইনকামিং বস্তুর হ্যাশ ব্যবহার যেমন লুক-না। member:, ধারক শুধু তাই এক দেখবে বালতি (এই কারণেই সদস্যপদ পরীক্ষায় অ্যারেগুলির তুলনায় সেটগুলি এত বেশি দ্রুত এবং অভিধান-কী কী-মূল্য অনুসন্ধানে সমান্তরাল অ্যারের তুলনায় অনেক দ্রুত হয়)। যদি অনুসন্ধান করা বস্তুর ভুল হ্যাশ থাকে তবে ধারকটি ভুল বালতিতে দেখবে এবং কোনও মিল খুঁজে পাবে না।
পিটার হোসে

@ পিটারহসে ওফস ... আমি ভুল করে ভেবেছিলাম যে এর ডিফল্ট বাস্তবায়ন -[NSObject hash]0 ছিল That এটি অনেক কিছুই ব্যাখ্যা করে। = এস
fumoboy007

31

এনএসএসেটের কোনও পদ্ধতি অবজেক্টঅ্যান্টেক্স নেই:

AllObjects কে কল করার চেষ্টা করুন যা সমস্ত বস্তুর NSArray দেয়।


অ্যারে ফিরিয়ে দেওয়া হলে অর্ডার দিলে আপনার কোনও ধারণা আছে? অন্য কথায়, যদি আমি "setByAddingObject" ব্যবহার করে সেটে বস্তুগুলি যুক্ত করি, এবং আমি "allObjects" ব্যবহার করি, তবে তা কি? অ্যারেতে থাকা উপাদানগুলি ক্রমে ক্রমযুক্ত আমি বস্তুগুলি যুক্ত করেছি?
iosMentalist

কেবলমাত্র একটি এনএসএসর্টপ্রেডিকেট দিয়ে ফলাফল অ্যারে বাছাই করুন এবং আপনি ভাল থাকবেন
জেসন

আপনি যদি কেবল একটি নির্দিষ্ট অবজেক্টে আগ্রহী হন তবে ফিল্টারসেটউজিংপ্রেডিকেট পদ্ধতির আরও ভাল ব্যবহার করুন।
akw

17

আপনার প্রয়োজনীয় অবজেক্টটি নির্বাচন করতে যদি কোনও ধরণের অনন্য শনাক্তকারী থাকে তবে ফিল্টারসেটসৌসিংপ্রেডিকেট ব্যবহার করা সম্ভব।

প্রথমে প্রিকিট তৈরি করুন (অবজেক্টটিতে আপনার অনন্য আইডি ধরে ধরে "সনাক্তকারী" বলা হয় এবং এটি একটি এনএসএস স্ট্রিং):

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

এবং তারপরে প্রিডিকেট ব্যবহার করে অবজেক্টটি চয়ন করুন:

NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;

13

NSArray *myArray = [myNSSet allObjects];

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

আপনার পছন্দসই অবজেক্টের সূচী দিয়ে এনএসইউইন্টারকে প্রতিস্থাপন করুন।


4
হওয়া উচিত: মাইবজেক্ট * অবজেক্ট = [মাইআরাই অবজেক্টআটিআইডেক্স: (এনএসইউআইঞ্জার *)]
জন ডি


6

এনএসএসেটটি হল একুয়াল পদ্ধতিটি ব্যবহার করে: (যেটি আপনি সেই সেটে রেখেছেন সেগুলি অবশ্যই ওভাররাইড করতে হবে, উপরন্তু, হ্যাশ পদ্ধতিটি) কোনও বস্তুর ভিতরে রয়েছে কিনা তা নির্ধারণ করতে।

সুতরাং, উদাহরণস্বরূপ যদি আপনার কাছে এমন কোনও ডেটা মডেল থাকে যা একটি আইডি মান দ্বারা এর স্বতন্ত্রতাটি সংজ্ঞায়িত করে (সম্পত্তিটি বলে:

@property NSUInteger objectID;

তাহলে আপনি ইস্কুল: বাস্তবায়ন করতেন

- (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
}

তারপরে, আপনি সেই আইডি সহ একটি বস্তু পেতে পারেন (পাশাপাশি এটি এনএসএসেটে রয়েছে কিনা তা পরীক্ষা করে দেখুন):

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

তবে হ্যাঁ, এনএসএসেট থেকে কিছু পাওয়ার একমাত্র উপায় হ'ল এটি বিবেচনা করা যা এটি তার স্বতন্ত্রতাটিকে প্রথম স্থানে সংজ্ঞায়িত করে।

আমি কী দ্রুত তা পরীক্ষা করেছি না, তবে আমি গণনাটি ব্যবহার করা এড়াচ্ছি কারণ এটি সদস্যের ব্যবহারের ক্ষেত্রে লিনিয়ার হতে পারে: পদ্ধতিটি আরও দ্রুত হবে। এটি এনএসআরির পরিবর্তে এনএসএসেটের ব্যবহারকে প্রাধান্য দেওয়ার অন্যতম কারণ।



0

বেশিরভাগ সময় আপনি সেট থেকে একটি নির্দিষ্ট অবজেক্ট পাওয়ার বিষয়ে চিন্তা করেন না। কোনও সেটে কোনও বস্তু রয়েছে কিনা তা পরীক্ষা করার বিষয়ে আপনার যত্নশীল। সেটাই সেটগুলির জন্য ভাল। যখন আপনি দেখতে চান যে কোনও বস্তু কোনও সংগ্রহের সেটে রয়েছে সেগুলি অ্যারের তুলনায় অনেক দ্রুত।

আপনি কোন বস্তুটি পেয়েছেন সে সম্পর্কে যদি চিন্তা না -anyObjectকরেন তবে সেট থেকে কেবল একটি জিনিস দেবে যেমন ব্যবহার করুন, ব্যাগের মধ্যে হাত রাখার এবং কোনও জিনিস ধরার মতো।

Dog *aDog = [dogs anyObject]; // dogs is an NSSet of Dog objects

আপনি কী কী বস্তু পাবেন সে সম্পর্কে যদি যত্নশীল হন -memberতবে আপনাকে ব্যবহার করে যা আপনাকে সেই বস্তুটি ফিরিয়ে দেয় বা সেটে না থাকলে শূন্য করে। কল করার আগে আপনার কাছে ইতিমধ্যে এটি থাকা উচিত।

Dog *spot = [Dog dogWithName:@"Spot"];
// ...
Dog *aDog = [dogs member:spot]; // Returns the same object as above

আরও কিছু বুঝতে আপনি এখানে কোড কোড চালিয়ে যেতে পারেন

NSString *one = @"One";
NSString *two = @"Two";
NSString *three = @"Three";

NSSet *set = [NSSet setWithObjects:one, two, three, nil];

// Can't use Objective-C literals to create a set.
// Incompatible pointer types initializing 'NSSet *' with an expression of type 'NSArray *'
//  NSSet *set = @[one, two, three];

NSLog(@"Set: %@", set);
// Prints looking just like an array but is actually not in any order
//Set: {(
//     One,
//     Two,
//     Three
//     )}

// Get a random object
NSString *random = [set anyObject];
NSLog(@"Random: %@", random); // Random: One

// Iterate through objects. Again, although it prints in order, the order is a lie
for (NSString *aString in set) {
    NSLog(@"A String: %@", aString);
}

// Get an array from the set
NSArray *array = [set allObjects];
NSLog(@"Array: %@", array);

// Check for an object
if ([set containsObject:two]) {
    NSLog(@"Set contains two");
}

// Check whether a set contains an object and return that object if it does (nil if not)
NSString *aTwo = [set member:two];
if (aTwo) {
    NSLog(@"Set contains: %@", aTwo);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.