Предикат за диапазон от NString в масив

Имам масив (NSArray), да речем

NSArray *cityArry = @[@"Chennai", @"Mumbai", @"Kolkata"];

Например споменах NSArray с 3 обекта, но всъщност по време на изпълнение имам масив, който съдържа повече от 1000 обекта.

Сега имам низа (NSString) "chennai Tnagar"

NSString *scanedStr = @"Chennai Tnagar";

И така, сега искам да разбера дали диапазонът от scanedStr се съдържа в cityArry. Например трябва да получа изход като @"Chennai" от cityArry.

Знам, че можем да направим това чрез зацикляне на NSArray и с помощта на rangeofstring можем да получим изхода. Тъй като имам повече от 1000 обекта, не искам да правя цикъл. Моля, насочете ме и ми помогнете как да разреша това.

Благодаря предварително


person Prashanth Rajagopalan    schedule 13.05.2014    source източник
comment
вашият алгоритъм ще съвпадне ли с Че?   -  person gaussblurinc    schedule 13.05.2014
comment
Не, не искам да получавам резултата, когато 'scannedstr' е 'che. Искам да го получа, когато NSSting 'scannedstr' е като 'chennai sometext', 'sometext chennai' и т.н.   -  person Prashanth Rajagopalan    schedule 13.05.2014
comment
но какво да кажем за Tnagar? Tnagar sometext и sometext Tnagar също ще бъдат съпоставени?   -  person gaussblurinc    schedule 13.05.2014


Отговори (3)


По принцип можете да разделите низа и да търсите масива в cityArry.

NSString *scannedStr = @"Chennai Tnager";

NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF in[cd] %@", [scannedStr componentsSeparatedByString:@" "]];

[cityArray filteredArrayUsingPredicate: predicate];
person Sandeep    schedule 13.05.2014
comment
УАУ... Благодаря много.. Работи като магия :) Но ме притеснява, това ли е оптимизираният начин да го направя? - person Prashanth Rajagopalan; 13.05.2014
comment
Да, предикатите са най-добрите начини за филтриране на колекция в Objective C. - person Sandeep; 13.05.2014
comment
@PrashanthRajagopalan: Изричният цикъл може да бъде по-бърз от предикат, сравнете stackoverflow.com/a/21158730/1187415 . - person Martin R; 13.05.2014
comment
Позволете ми да представя някои разширени тестови данни за вашия алгоритъм: cityArry = @[@"Chennai", @"New York"] и scannedStr = @"New York City". Този алгоритъм дава ли желания резултат? - person Monolo; 13.05.2014
comment
@MartinR в къщата! Почти съм сигурен, че информацията в отговора ми е от коментар или отговор, направен от вас на друг въпрос. Има ли шанс да го изровиш? Не мога да го намеря. - person Monolo; 13.05.2014
comment
Да, наистина трябва да съответства на New York в масива, тъй като поднизовете New, York от scannedStr съвпадат с него. - person Sandeep; 13.05.2014
comment
@insane-36 Опитвал ли си да го стартираш? Не произвежда това, което бих очаквал (да съответства на Ню Йорк в масива), когато го стартирам, но може да съм направил грешка. - person Monolo; 13.05.2014
comment
@Monolo Добър улов. Проверих го. Не работи за „Ню Йорк Сити“. В такъв случай отговорът ви е перфектен. - person Prashanth Rajagopalan; 13.05.2014

Сигурен съм, че това е дубликат на друг отговор, но не мога да го намеря. Ако някой може, моля, затворете това като глупак.

Както и да е, операторът IN работи добре на низове. Очевидно е недокументирано, така че ще трябва да решите дали искате да разчитате на него:

NSArray *cityArray = @[@"Chennai",@"Mumbai",@"Kolkata"];

NSString *scannedStr = @"Chennai Tnagar";

NSPredicate *pred = [NSPredicate predicateWithFormat: @"SELF IN[cd] %@", scannedStr];

NSArray *result = [cityArray filteredArrayUsingPredicate: pred];

Това решение има предимството да запази обекта на предиката отляво, което ми се струва по-лесно за четене - но както споменахме, не е документирано.

В случай, че искате да използвате документирана конструкция, можете да размените реда на предиката и да използвате нормален CONTAINS:

pred = [NSPredicate predicateWithFormat: @"%@ CONTAINS[cd] SELF", scannedStr];
person Monolo    schedule 13.05.2014
comment
Публикувах подобен отговор (stackoverflow.com/a/23594103/1187415), но го изтрих по-късно поради това поведение е недокументирано и тъй като @insane-36 показа в своя отговор (stackoverflow.com/a/23594199/1187415) на същият въпрос, че това може да се постигне с по-опростен документиран предикат. - person Martin R; 13.05.2014
comment
@Monolo Отговорът ти е перфектен. Но вие казвате, че е недокументирано. Мога ли да го използвам? - person Prashanth Rajagopalan; 13.05.2014
comment
@PrashanthRajagopalan Всъщност малко се заблудих от @MartinR's от вчера, който използва елегантния IN. Можете просто да обърнете предиката и да използвате документирания CONTAINS във форматния низ, като този: @"%@ CONTAINS[cd] SELF". Ще актуализирам отговора. - person Monolo; 13.05.2014

Предлагам ви да използвате SQL заявка like, като използвате sqlite3 като база данни на списъка с всички градове, които имате. Малко болезнено е внедряването на база данни, но според мен решава проблема.

person Thanh-Nhon Nguyen    schedule 13.05.2014