উদ্দেশ্য-সি-তে নতুন এনএসআরিতে এনএসআরিকে ফিল্টার করা হচ্ছে


121

আমার একটি রয়েছে NSArrayএবং আমি NSArrayনির্দিষ্ট মাপদণ্ডের সাথে মিলিত মূল অ্যারে থেকে অবজেক্টগুলির সাথে একটি নতুন তৈরি করতে চাই । মানদণ্ডটি একটি ফাংশন দ্বারা সিদ্ধান্ত নেওয়া হয় যা a BOOL

আমি NSMutableArrayউত্স অ্যারের মাধ্যমে একটি তৈরি করতে পারি , ফিল্টার ফাংশন গ্রহণ করে এমন বস্তুগুলির অনুলিপি করতে পারি এবং তারপরে এটির অপরিবর্তনীয় সংস্করণ তৈরি করতে পারি।

একটি ভাল উপায় আছে কি?

উত্তর:


140

NSArrayএবং NSMutableArrayঅ্যারে সামগ্রীগুলিকে ফিল্টার করার জন্য পদ্ধতি সরবরাহ করুন। ফিল্টারডআরয়েউজিংপ্রেডিকেট সরবরাহ করে: যা রিসিভারে একটি নতুন অ্যারে NSArrayপ্রদান করে যা নির্দিষ্ট প্রিকিকেটের সাথে মেলে। জোড়ে filterUsingPredicate: যা নির্দিষ্ট সম্পৃক্ত এবং পাতা বিরুদ্ধে রিসিভারের বিষয়বস্তু মূল্যায়ন শুধু তাই ম্যাচ অবজেক্ট। এই পদ্ধতিগুলি নিম্নলিখিত উদাহরণে চিত্রিত হয়।NSMutableArray

NSMutableArray *array =
    [NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];

NSPredicate *bPredicate =
    [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
    [array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.

NSPredicate *sPredicate =
    [NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filteredArrayUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }

84
আমি পাপা স্মারফের পডকাস্ট শুনেছি এবং পাপা স্মুরফ বলেছেন উত্তরগুলি স্ট্যাকওভারফ্লোতে বাস করা উচিত যাতে সম্প্রদায়টি তাদের রেট দেয় এবং উন্নতি করতে পারে।
willc2

10
@ ম্যামাল্ক - সম্ভবত আরও সংখ্যক,
ব্রায়ান

5
এনএসপ্রেডিকেট মারা গেছে, দীর্ঘ লাইভ ব্লক! cf. আমার উত্তর নীচে।
ক্লে ব্রিজগুলি

[সি] এর অর্থ কী? আমি সবসময় [সি] দেখি তবে বুঝতে পারি না এটি কী করে?
ব্যবহারকারী 1007522

3
@ ব্যবহারকারী 1007522, [সি] ম্যাচ কেস-সংবেদনশীল করে তোলে
জোনবাউর

104

এটি করার জন্য প্রচুর উপায় রয়েছে, তবে এখন পর্যন্ত নিকটতম অবশ্যই ব্যবহার করছে [NSPredicate predicateWithBlock:]:

NSArray *filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
    return [object shouldIKeepYou];  // Return YES for each object you want in filteredArray.
}]];

আমি মনে করি এটি যতটা সংক্ষিপ্ত আকারে তা পায়।


সুইফট:

যারা NSArrayসুইফটে এস নিয়ে কাজ করছেন , আপনি এটিকে আরও সংক্ষিপ্ত সংস্করণটি পছন্দ করতে পারেন :

nsArray = nsArray.filter { $0.shouldIKeepYou() }

filterএটি কেবলমাত্র একটি পদ্ধতি Array( NSArrayসম্পূর্ণভাবে সুইফ্টের সাথে ব্রিজ করা হয় Array)। এটির একটি যুক্তি লাগে: একটি সমাপ্তি যা অ্যারেতে একটি অবজেক্ট নেয় এবং a এ দেয় Bool। আপনার বন্ধের trueমধ্যে, ফিল্টার করা অ্যারেতে আপনি যে কোনও অবজেক্ট চান তার জন্য কেবল ফিরে আসুন।


1
এনএসডেটরিয় * বাঁধাই এখানে কী ভূমিকা পালন করছে?
কাইতাইন

@ কেইটাইন বাইন্ডিংগুলি NSPredicate predicateWithBlock:এপিআই দ্বারা প্রয়োজনীয় ।
থমাস ডাব্লু

@ কেইটাইন অভিধানে bindingsটেমপ্লেটগুলির জন্য ভেরিয়েবল বাইন্ডিং থাকতে পারে।
আমিন নেগম-আওয়াদ

জটিল বস্তুগুলির সাথে লেনদেন করার সময় গৃহীত উত্তরের চেয়ে অনেক বেশি কার্যকর :)
বেন লেগজিও

47

ক্লে ব্রিজের উত্তরের ভিত্তিতে, ব্লকগুলি ব্যবহার করে ফিল্টারিংয়ের একটি উদাহরণ ( yourArrayআপনার অ্যারে ভেরিয়েবলের নাম এবং testFuncআপনার পরীক্ষার ক্রিয়াকলাপের নাম পরিবর্তন করুন ):

yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [self testFunc:obj];
}]];

পরিশেষে একটি উত্তর কেবল ব্লকগুলির সাথে ফিল্টারিংয়ের কথা উল্লেখ করে না, এটি কীভাবে করা যায় তার একটি ভাল উদাহরণ দেয়। ধন্যবাদ।
ক্রিস্টিয়ান

আমি এই উত্তরটি পছন্দ করি; যদিও filteredArrayUsingPredicateঝুঁকিপূর্ণ, আপনি যে কোনও ভবিষ্যদ্বাণীমূলক ধরণের ব্যবহারকে অস্পষ্ট করেন না তা এই উদ্দেশ্যটি।
জেমস পেরিহ

এটি করার জন্য এটি সবচেয়ে আধুনিক উপায়। ব্যক্তিগতভাবে আমি পুরানো শর্টহ্যান্ড "অবজেক্টস পাসিংস্টেস্ট" এর জন্য আগ্রহী যা নির্দিষ্ট সময়ে API থেকে অদৃশ্য হয়ে যায়। তবু এটি দ্রুত এবং ভাল চলমান। আমি এনএসপ্রেডিকেটকে পছন্দ করি - তবে অন্যান্য জিনিসের জন্য যেখানে ভারী হাতুড়ি দরকার
মোটি শ্নের

আপনি এখন ত্রুটি পাবেন Implicit conversion of 'NSUInteger' (aka 'unsigned long') to 'NSIndexSet * _Nonnull' is disallowed with ARC... এটি এনএসআইএনডেক্সসেটস আশা করে
anoop4real

@ আনুপ 4 রিয়াল, আমি মনে করি আপনি যে সতর্কতার কথা উল্লেখ করেছেন তার কারণ হ'ল আপনি ভুল করে indexOfObjectPassingTestপরিবর্তে ব্যবহার করেছেন indexesOfObjectsPassingTest। মিস করা সহজ, তবে বড় পার্থক্য :)
প্যাকিল

46

আপনি যদি ওএস এক্স 10.6 / আইওএস 4.0 বা তার পরে থাকেন তবে আপনি সম্ভবত এনএসপ্রেডিকেটের চেয়ে ব্লক দিয়ে ভাল। -[NSArray indexesOfObjectsPassingTest:]একটি সহজ -select:বা -filter:পদ্ধতি যুক্ত করার জন্য আপনার নিজস্ব বিভাগ দেখুন বা লিখুন ( উদাহরণ )।

অন্য কেউ চান যে বিভাগটি লিখুন, এটি পরীক্ষা করুন, ইত্যাদি? পরীক্ষা করে দেখুন BlocksKit ( অ্যারে ডক্স )। এবং আরও অনেক উদাহরণ পাওয়া যায়, যেমনটি বলে, যেমন "নসরার ব্লক বিভাগ নির্বাচন করুন" সন্ধান করুন


5
আপনি একটি উদাহরণ সহ আপনার উত্তর প্রসারিত আপত্তি করতে চান? আপনার যখন সর্বাধিক প্রয়োজন হয় তখন ব্লগ ওয়েবসাইটগুলিতে মারা যাওয়ার প্রবণতা থাকে।
ড্যান আব্রামভ

8
লিঙ্ক পচা থেকে সুরক্ষা প্রাসঙ্গিক কোড এবং লিঙ্কযুক্ত নিবন্ধ থেকে নোট না, আরও লিঙ্ক যোগ না। লিঙ্কগুলি রাখুন, তবে কয়েকটি উদাহরণ কোড যুক্ত করুন।
টুলবার

3
@ ক্লেব্রিজেস আমি এই প্রশ্নটি কোকোতে ফিল্টার করার উপায়গুলির সন্ধান করতে পেয়েছি। যেহেতু আপনার উত্তরে কোনও কোডের নমুনা নেই, তাই ব্লকগুলি আমার কী প্রয়োজন তা অর্জন করবে না তা জানতে আপনার লিঙ্কগুলি খনতে আমাকে প্রায় 5 মিনিট সময় লেগেছে। কোডটির উত্তরটি থাকলে এটি সম্ভবত 30 সেকেন্ড সময় নেয়। এই উত্তরটি আসল কোড ব্যতীত কম কম কার্যকর।
এন_এ

1
@ মাইডোগিসবক্স এবং অন্যান্য: এখানে কেবলমাত্র 4 টি উত্তর রয়েছে এবং এইভাবে আপনার নিজের একটি চকচকে ও উচ্চতর কোড-স্যাম্পলড উত্তরের জন্য প্রচুর জায়গা রয়েছে। আমি আমার সাথে খুশি, তাই দয়া করে এটি একা ছেড়ে দিন।
ক্লে সেতু

2
মাইডোগিসবক্স ঠিক এই পয়েন্টে ঠিক আছে; যদি আপনি যা করছেন সমস্ত একটি লিঙ্ক সরবরাহ করছে তবে আপনি আরও লিঙ্ক যুক্ত করলেও এটি সত্যিই একটি উত্তর নয়। মেটা.স্ট্যাকেক্সেঞ্জার.কম / সেকশনগুলি / ৮৮৩১ দেখুন । লিটমাস টেস্ট: আপনার উত্তরটি কি নিজেরাই দাঁড়াতে পারে, বা লিঙ্কগুলি ক্লিক করার কোনও মূল্য হওয়া দরকার? বিশেষত, আপনি উল্লেখ করেছেন যে "আপনি সম্ভবত এনএসপিডিকেটের চেয়ে ব্লকগুলি থেকে ভাল but" তবে আপনি কেন এটি ব্যাখ্যা করেন না।
রবার্ট হার্ভে

16

ধরে নিবেন যে আপনার অবজেক্টগুলি সমস্ত একই ধরণের, আপনি তাদের বেস বর্গের একটি বিভাগ হিসাবে একটি পদ্ধতি যুক্ত করতে পারেন যা আপনার মানদণ্ডের জন্য আপনি যে ফাংশনটি ব্যবহার করছেন তা কল করে। তারপরে একটি এনএসপ্রেডিকেট অবজেক্ট তৈরি করুন যা সেই পদ্ধতিটিকে বোঝায়।

কিছু বিভাগে আপনার কার্যটি ব্যবহার করে এমন আপনার পদ্ধতিটি নির্ধারণ করুন

@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
    return someComparisonFunction(self, whatever);
}
@end

তারপরে আপনি যেখানেই ফিল্টারিং করবেন:

- (NSArray *)myFilteredObjects {
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
    return [myArray filteredArrayUsingPredicate:pred];
}

অবশ্যই, যদি আপনার ফাংশনটি কেবল আপনার শ্রেণীর মধ্যে থেকে পৌঁছতে পারে এমন বৈশিষ্ট্যের সাথে তুলনা করে তবে ফাংশনের শর্তগুলিকে একটি প্রাকটিক স্ট্রিংয়ে রূপান্তর করা আরও সহজ।


আমি এই উত্তরটি পছন্দ করেছি, কারণ এটি করুণ এবং সংক্ষিপ্ত, এবং কীভাবে সর্বাধিক প্রাথমিক জিনিসটির জন্য এনএসপ্রেডিকেটকে আনুষ্ঠানিকভাবে আনতে হবে - পুনর্বার সংস্থান এবং বুলিয়ান পদ্ধতিতে শিখতে হবে। এমনকি আমি মনে করি যে মোড়কের দরকার ছিল না। একটি সরল [মাইআরাই ফিল্টারড অ্যারে ইউসিং প্রেডিকেট: [এনএসপ্রেডিকেট প্রিডিকেট উইথফর্ম্যাট: @ "মাইমেথড = সত্য"]]; যথেষ্ট হবে। ধন্যবাদ! (আমি বিকল্পগুলিও পছন্দ করি তবে এটি একটি দুর্দান্ত)।
মোটি শ্নের

3

NSPredicateএকটি সংগ্রহ ফিল্টার শর্ত নির্মানের NEXTSTEP এর উপায় ( NSArray, NSSet, NSDictionary)।

উদাহরণস্বরূপ দুটি অ্যারে বিবেচনা করুন arrএবং filteredarr:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];

filteredarr = [NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];

ফিল্টারডায়ার অবশ্যই আইটেমগুলিতে একক অক্ষর ধারণ করে।

যারা খুব কম স্কয়ারের পটভূমি তাদের মনে রাখা সহজ করে তুলতে

*--select * from tbl where column1 like '%a%'--*

1) টিবিএল -> সংগ্রহ থেকে * নির্বাচন করুন

2) '% a%' -> এর মতো কলাম 1NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];

3) টিবিএল থেকে * নির্বাচন করুন যেখানে কলাম 1 '% a%' -> পছন্দ করে

[NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];

আশা করি এটা কাজে লাগবে


2

NSArray + + Xh

@interface NSArray (X)
/**
 *  @return new NSArray with objects, that passing test block
 */
- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate;
@end

NSArray + + xm

@implementation NSArray (X)

- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate
{
    return [self objectsAtIndexes:[self indexesOfObjectsPassingTest:predicate]];
}

@end

আপনি এই বিভাগটি এখানে ডাউনলোড করতে পারেন


0

এই লাইব্রেরি চেকআউট করুন

https://github.com/BadChoice/Collection

এটি আবার কখনও লুপটি না লেখার জন্য প্রচুর সহজ অ্যারে ফাংশন সহ আসে

সুতরাং আপনি ঠিক করতে পারেন:

NSArray* youngHeroes = [self.heroes filter:^BOOL(Hero *object) {
    return object.age.intValue < 20;
}];

অথবা

NSArray* oldHeroes = [self.heroes reject:^BOOL(Hero *object) {
    return object.age.intValue < 20;
}];

0

সর্বোত্তম ও সহজ উপায় হ'ল এই পদ্ধতিটি তৈরি করা এবং অ্যারে এবং মানটি পাস করা:

- (NSArray *) filter:(NSArray *)array where:(NSString *)key is:(id)value{
    NSMutableArray *temArr=[[NSMutableArray alloc] init];
    for(NSDictionary *dic in self)
        if([dic[key] isEqual:value])
            [temArr addObject:dic];
    return temArr;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.