Предикат для диапазона 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 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 немного сбил меня с толку, в котором используется элегантный IN. Вы можете просто перевернуть предикат и использовать задокументированный CONTAINS в строке формата, например: @"%@ CONTAINS[cd] SELF". Я обновлю ответ. - person Monolo; 13.05.2014

Я предлагаю вам использовать SQL-запрос like, используя sqlite3 в качестве базы данных списка всех городов, которые у вас есть. Немного болезненно внедрять базу данных, но я думаю, что это решает проблему.

person Thanh-Nhon Nguyen    schedule 13.05.2014