উদ্দেশ্য-সি NSString
থেকে সদৃশ মান ( ) অপসারণ করার সর্বোত্তম উপায় NSMutableArray
?
এটি কি এটি করার সবচেয়ে সহজ এবং সঠিক উপায়?
uniquearray = [[NSSet setWithArray:yourarray] allObjects];
উদ্দেশ্য-সি NSString
থেকে সদৃশ মান ( ) অপসারণ করার সর্বোত্তম উপায় NSMutableArray
?
এটি কি এটি করার সবচেয়ে সহজ এবং সঠিক উপায়?
uniquearray = [[NSSet setWithArray:yourarray] allObjects];
উত্তর:
আপনার NSSet
পন্থাটি সর্বোত্তম যদি আপনি বস্তুর ক্রম সম্পর্কে উদ্বিগ্ন না হন তবে আবার যদি আপনি আদেশ সম্পর্কে উদ্বিগ্ন না হন তবে কেন আপনি সেগুলি NSSet
শুরু করার জন্য সংরক্ষণ করছেন না ?
আমি নীচে উত্তরটি 2009 সালে লিখেছি; ২০১১-এ, অ্যাপল NSOrderedSet
আইওএস 5 এবং ম্যাক ওএস এক্স 10.7-এ যুক্ত করেছে। অ্যালগরিদম যা ছিল তা এখন দুটি লাইনের কোড:
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourArray];
NSArray *arrayWithoutDuplicates = [orderedSet array];
যদি আপনি অর্ডারটি সম্পর্কে উদ্বিগ্ন হন এবং আপনি আইওএস 4 বা তার আগের দিকে চলছেন তবে অ্যারের অনুলিপিটি লুপ করুন:
NSArray *copy = [mutableArray copy];
NSInteger index = [copy count] - 1;
for (id object in [copy reverseObjectEnumerator]) {
if ([mutableArray indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound) {
[mutableArray removeObjectAtIndex:index];
}
index--;
}
[copy release];
[NSOrderedSet orderedSetWithArray:array];
আপনি তারপরে একটি অ্যারে ফিরে পেতে পারেন array = [orderedSet allObjects];
বা কেবলমাত্র প্রথম স্থানে না ব্যবহার করে NSOrderedSet
s NSArray
[orderedSet allObjects]
সঙ্গে প্রতিস্থাপন করা প্রয়োজন [orderedSet array]
!
NSArray
এবং তৈরি করি NSMutableArray
। আপনার উদাহরণে আপনি বিপরীতে কাজ করেন
আমি জানি এটি একটি পুরানো প্রশ্ন, তবে NSArray
আপনি যদি অর্ডারটি যত্ন না করেন তবে নকলকে সরিয়ে ফেলার আরও একটি দুর্দান্ত উপায় রয়েছে ।
যদি আমরা কী মান কোডিং থেকে অবজেক্ট অপারেটর ব্যবহার করি তবে আমরা এটি করতে পারি:
uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"];
হিসাবে AnthoPak লক্ষনীয় এটি একটি সম্পত্তি উপর ভিত্তি করে সদৃশ অপসারণ করা সম্ভব। একটি উদাহরণ হবে:@distinctUnionOfObjects.name
@distinctUnionOfObjects.property
কাস্টম অবজেক্টগুলির একটি অ্যারের সম্পত্তি দ্বারা সদৃশগুলি সরানোর মতোও ব্যবহার করা যেতে পারে । উদাহরণস্বরূপ@distinctUnionOfObjects.name
হ্যাঁ, এনএসএসেট ব্যবহার করা একটি বোধগম্য পদ্ধতি।
জিম পালসের উত্তরে যুক্ত করতে, অর্ডার বজায় রেখে ডুপ্লিকেটগুলি সরিয়ে ফেলার বিকল্প বিকল্প এখানে রয়েছে:
// Initialise a new, empty mutable array
NSMutableArray *unique = [NSMutableArray array];
for (id obj in originalArray) {
if (![unique containsObject:obj]) {
[unique addObject:obj];
}
}
এটি মূলত জিমের মতোই একই পদ্ধতির তবে অনুলিপি আইটেমগুলিকে আসল থেকে নকল মুছে ফেলার পরিবর্তে একটি তাজা পরিবর্তনযোগ্য অ্যারে অনুলিপি করে। প্রচুর নকল (পুরো অ্যারের একটি অনুলিপি তৈরি করার প্রয়োজন নেই) সহ বৃহত অ্যারের ক্ষেত্রে এটি সামান্য আরও মেমরির দক্ষ করে তোলে এবং আমার মতে এটি আরও কিছুটা পাঠযোগ্য read
মনে রাখবেন যে উভয় ক্ষেত্রেই, কোনও আইটেম ইতিমধ্যে লক্ষ্য অ্যারেতে অন্তর্ভুক্ত রয়েছে কিনা তা পরীক্ষা করে নেওয়া ( containsObject:
আমার উদাহরণে বা indexOfObject:inRange:
জিমের ব্যবহার করে) বড় অ্যারেগুলিতে ভাল স্কেল করে না। এই চেকগুলি ও (এন) সময়ে চালিত হয়, এর অর্থ আপনি যদি মূল অ্যারের আকার দ্বিগুণ করেন তবে প্রতিটি চেক চালাতে দ্বিগুণ সময় নিতে হবে। যেহেতু আপনি অ্যারেতে প্রতিটি বস্তুর জন্য চেক করছেন, তাই আপনি আরও বেশি ব্যয়বহুল চেকগুলি আরও চালাবেন। সামগ্রিক অ্যালগরিদম (আমার এবং জিম উভয়ই) ও (এন 2 ) সময়ে চলে যা মূল অ্যারে বাড়ার সাথে সাথে ব্যয়বহুল হয়ে ওঠে।
ও (এন) এর সময় নেওয়ার জন্য আপনি NSMutableSet
ইতিমধ্যে নতুন অ্যারেতে যুক্ত হওয়া আইটেমগুলির একটি রেকর্ড সংরক্ষণ করতে একটি ব্যবহার করতে পারেন , যেহেতু এনএসএসেট লকআপগুলি ও (এন) এর পরিবর্তে ও (1) হয়। অন্য কথায়, কোনও উপাদান এনএসএসেটের সদস্য কিনা তা যাচাই করতে সেটে কতগুলি উপাদান রয়েছে তা নির্বিশেষে একই সময় নেয়।
এই পদ্ধতির সাহায্যে কোডটি দেখতে এরকম কিছু দেখতে পাবে:
NSMutableArray *unique = [NSMutableArray array];
NSMutableSet *seen = [NSMutableSet set];
for (id obj in originalArray) {
if (![seen containsObject:obj]) {
[unique addObject:obj];
[seen addObject:obj];
}
}
এটি এখনও কিছুটা অপব্যয় মনে হলেও; আমরা এখনও একটি নতুন অ্যারে তৈরি করছি যখন প্রশ্নটি পরিষ্কার হয়ে গেছে যে মূল অ্যারেটি পরিবর্তনযোগ্য, তাই আমাদের এটি জায়গায় ডি-ডুপ করতে এবং কিছু স্মৃতি সংরক্ষণ করতে সক্ষম হওয়া উচিত। এটার মতো কিছু:
NSMutableSet *seen = [NSMutableSet set];
NSUInteger i = 0;
while (i < [originalArray count]) {
id obj = [originalArray objectAtIndex:i];
if ([seen containsObject:obj]) {
[originalArray removeObjectAtIndex:i];
// NB: we *don't* increment i here; since
// we've removed the object previously at
// index i, [originalArray objectAtIndex:i]
// now points to the next object in the array.
} else {
[seen addObject:obj];
i++;
}
}
আপডেট : ইউরি নিয়াজভ উল্লেখ করেছিলেন যে আমার শেষ উত্তরটি আসলে ও (এন 2 ) এ চলে কারণ removeObjectAtIndex:
সম্ভবত ও (এন) সময়ে চলে।
(তিনি "সম্ভবত" বলেছেন কারণ এটি কীভাবে কার্যকর করা হয়েছে তা আমরা নিশ্চিতভাবে জানি না; তবে একটি সম্ভাব্য বাস্তবায়ন হ'ল সূচি এক্সে অবজেক্টটি মোছার পরে পদ্ধতিটি সূচি এক্স + 1 থেকে অ্যারের শেষ অবজেক্টে প্রতিটি উপাদানকে লুপ করে তোলে) , তাদের পূর্বের সূচকে সরানো।
তো এখন কি করা? এটা পরিস্থিতির উপর নির্ভর করে। যদি আপনি একটি বড় অ্যারে পেয়ে থাকেন এবং আপনি কেবলমাত্র কয়েকটি সংখ্যক নকলের প্রত্যাশা করছেন তবে স্থানের ডি-সদৃশটি ঠিক কাজ করবে এবং আপনাকে একটি সদৃশ অ্যারে তৈরির সংরক্ষণ করবে। যদি আপনি এমন একটি অ্যারে পেয়ে থাকেন যেখানে আপনি প্রচুর নকলের প্রত্যাশা করছেন তবে আলাদা, ডি-ডুপড অ্যারে তৈরি করা সম্ভবত সেরা পন্থা। এখানে সরানোর বিষয়টি হ'ল বিগ-ও স্বরলিপিটি কেবল একটি অ্যালগরিদমের বৈশিষ্ট্য বর্ণনা করে, এটি আপনাকে নির্দিষ্ট করে বলতে পারে না যে কোনও প্রদত্ত পরিস্থিতিতে সবচেয়ে ভাল।
আপনি যদি আইওএস 5+ (পুরো আইওএস ওয়ার্ল্ড জুড়ে) কে লক্ষ্য করে নিচ্ছেন তবে সেরা ব্যবহার করুন NSOrderedSet
। এটি সদৃশগুলি সরায় এবং আপনার ক্রমটি ধরে রাখে NSArray
।
শুধু কর
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourArray];
আপনি এখন এটি একটি অনন্য NSArray এ আবার রূপান্তর করতে পারেন
NSArray *uniqueArray = orderedSet.array;
কারণ এটি মতো NSArray মত একই পদ্ধতি আছে অথবা শুধু orderedSet ব্যবহার objectAtIndex:
, firstObject
ইত্যাদি।
এর সাথে সদস্যপদ পরীক্ষা contains
করা তার NSOrderedSet
চেয়ে দ্রুততর হয় anNSArray
আরও চেকআউট করার জন্য এনএসআরআরডসেট রেফারেন্স
ওএস এক্স v10.7 এবং তার পরে পাওয়া যায়।
আপনি যদি অর্ডার সম্পর্কে উদ্বিগ্ন হন তবে সঠিক উপায় way
NSArray *no = [[NSOrderedSet orderedSetWithArray:originalArray]allObjects];
অর্ডার ইন এনএসআরাই থেকে সদৃশ মানগুলি অপসারণের কোডটি এখানে।
আদেশ প্রয়োজন
NSArray *yourarray = @[@"a",@"b",@"c"];
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourarray];
NSArray *arrayWithoutDuplicates = [orderedSet array];
NSLog(@"%@",arrayWithoutDuplicates);
বা আদেশ প্রয়োজন নেই
NSSet *set = [NSSet setWithArray:yourarray];
NSArray *arrayWithoutOrder = [set allObjects];
NSLog(@"%@",arrayWithoutOrder);
এখানে আমি মেনআর্রে থেকে অনুলিপি নামের মানগুলি সরিয়েছি এবং এনএসমেটেবালআরির তালিকার ফলাফল (listOfUserrs)
for (int i=0; i<mainArray.count; i++) {
if (listOfUsers.count==0) {
[listOfUsers addObject:[mainArray objectAtIndex:i]];
}
else if ([[listOfUsers valueForKey:@"name" ] containsObject:[[mainArray objectAtIndex:i] valueForKey:@"name"]])
{
NSLog(@"Same object");
}
else
{
[listOfUsers addObject:[mainArray objectAtIndex:i]];
}
}
মনে রাখবেন যে আপনার যদি সাজানো অ্যারে থাকে তবে আপনাকে অ্যারেতে থাকা সমস্ত আইটেমের বিরুদ্ধে চেক করার দরকার নেই, কেবলমাত্র শেষ আইটেম। এটি সমস্ত আইটেমের বিরুদ্ধে চেক করার চেয়ে অনেক দ্রুত হওয়া উচিত।
// sortedSourceArray is the source array, already sorted
NSMutableArray *newArray = [[NSMutableArray alloc] initWithObjects:[sortedSourceArray objectAtIndex:0]];
for (int i = 1; i < [sortedSourceArray count]; i++)
{
if (![[sortedSourceArray objectAtIndex:i] isEqualToString:[sortedSourceArray objectAtIndex:(i-1)]])
{
[newArray addObject:[tempArray objectAtIndex:i]];
}
}
দেখে মনে হচ্ছে এমন NSOrderedSet
উত্তরের মত দেখতেও অনেক কম কোডের প্রয়োজন, তবে আপনি যদি NSOrderedSet
কোনও কারণে ব্যবহার করতে না পারেন এবং আপনার সাজানো অ্যারে থাকে তবে আমি বিশ্বাস করি যে আমার সমাধানটি সবচেয়ে দ্রুত হবে। আমি নিশ্চিত না যে এটি কীভাবে NSOrderedSet
সমাধানগুলির গতির সাথে তুলনা করে । এছাড়াও নোট করুন যে আমার কোডটি চেক করছে isEqualToString:
, সুতরাং একই সিরিজের চিঠিগুলি একাধিকবার প্রদর্শিত হবে না newArray
। আমি নিশ্চিত না যে NSOrderedSet
সমাধানগুলি মানের ভিত্তিতে বা মেমরির অবস্থানের ভিত্তিতে সদৃশগুলি সরিয়ে ফেলবে কিনা ।
আমার উদাহরণটি ধরে নিয়েছে যে sortedSourceArray
কেবলমাত্র NSString
এস, জাস্ট NSMutableString
এস, বা দুটিটির মিশ্রণ রয়েছে। sortedSourceArray
পরিবর্তে যদি কেবল NSNumber
এস বা জাস্ট NSDate
গুলি থাকে তবে আপনি প্রতিস্থাপন করতে পারেন
if (![[sortedSourceArray objectAtIndex:i] isEqualToString:[sortedSourceArray objectAtIndex:(i-1)]])
সঙ্গে
if ([[sortedSourceArray objectAtIndex:i] compare:[sortedSourceArray objectAtIndex:(i-1)]] != NSOrderedSame)
এবং এটি পুরোপুরি কাজ করা উচিত। যদি s, s এবং / অথবা s এর sortedSourceArray
মিশ্রণ থাকে তবে এটি সম্ভবত ক্রাশ হবে।NSString
NSNumber
NSDate
এখানে কেভিসি অবজেক্ট অপারেটর রয়েছে যা আরও মার্জিত সমাধান দেয় uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"];
এখানে একটি এনএসআরাই বিভাগ রয়েছে ।
আর একটি সহজ উপায় আপনি চেষ্টা করে দেখতে পারেন যা অ্যারেতে অবজেক্ট যুক্ত করার আগে সদৃশ মান যুক্ত করবে না: -
// ধরুন পরিবর্তনীয়আরিকে বরাদ্দ দেওয়া হয়েছে এবং আরম্ভ করা হবে এবং এতে কিছু মান রয়েছে
if (![yourMutableArray containsObject:someValue])
{
[yourMutableArray addObject:someValue];
}
উদ্দেশ্য-সি-তে NSMutableArray থেকে সদৃশ মানগুলি সরান
NSMutableArray *datelistArray = [[NSMutableArray alloc]init];
for (Student * data in fetchStudentDateArray)
{
if([datelistArray indexOfObject:data.date] == NSNotFound)
[datelistArray addObject:data.date];
}
এনএসমিটেবল অ্যারে থেকে সদৃশ মানগুলি অপসারণের কোডটি এখানে। .এটি আপনার পক্ষে কাজ করবে। মাইআরাই আপনার মিউটেটেবল অ্যারে যা আপনি সদৃশ মানগুলি মুছতে চান ..
for(int j = 0; j < [myMutableArray count]; j++){
for( k = j+1;k < [myMutableArray count];k++){
NSString *str1 = [myMutableArray objectAtIndex:j];
NSString *str2 = [myMutableArray objectAtIndex:k];
if([str1 isEqualToString:str2])
[myMutableArray removeObjectAtIndex:k];
}
} // Now print your array and will see there is no repeated value
এই সহজ কোডটি ব্যবহার করুন:
NSArray *hasDuplicates = /* (...) */;
NSArray *noDuplicates = [[NSSet setWithArray: hasDuplicates] allObjects];
যেহেতু nsset সদৃশ মানকে অনুমতি দেয় না এবং সমস্ত বস্তু একটি অ্যারে প্রদান করে returns
NSOrderedSet
insteed ব্যবহার করুন NSSet
।