NSPredicate: как НЕ EndsWith?

У меня есть список изображений в комплекте приложений, и мне нужно отобразить соответствующие изображения в приложении, изображение имеет формат:

###_photo_#.jpg

###: toy id, from 1000 to 2000
#: photo id, from 1

так например

1000_photo_1.jpg
1000_photo_2.jpg

Раньше я получал список файлов в комплекте и использовал предикат для фильтрации других файлов:

@"self ENDSWITH '.jpg' AND self BEGINSWITH '%d_photo_'", toyId

но теперь есть изображения сетчатки, которые заканчиваются на @2x.jpg, поэтому этот метод нужно исправить, я думаю добавить:

NOT ENDSWITH '@2x.jpg'

но правильно ли это? я должен сказать:

NOT (ENDSWITH '@2x.jpg')

or:

(NOT ENDSWITH '@2x.jpg')

вместо?


person hzxu    schedule 02.08.2012    source источник
comment
Любая причина, по которой вы не могли использовать predicateWithBlock?   -  person Jessedc    schedule 02.08.2012


Ответы (4)


Я думаю, что лучшим вариантом в iOS 4.0+ является использование NSPredicate predicateWithBlock: для определения ваших условий. Таким образом, вы можете использовать стандартные функции NSString, такие как hasSuffix:, чтобы проверить свой конец с отрицательным регистром.

Ознакомьтесь с хорошим руководством здесь: http://www.wannabegeek.com/?p=149.

Вот основной способ, которым вы могли бы его использовать.

NSInteger toyId = 10;
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
  return [evaluatedObject hasSuffix:@".jpg"] &&
  ![evaluatedObject hasSuffix:@"@2x.jpg"] &&
  [evaluatedObject hasPrefix:[NSString stringWithFormat:@"%@_photo_", [NSNumber numberWithInt:toyId]]];
}];

Затем вы можете получить свой массив файлов

[arrayOfFiles filterArrayUsingPredicate:predicate];
person Jessedc    schedule 02.08.2012
comment
Но predicateWithBlock не работает с магазином SQLite, верно? Если вы используете хранилище SQLite, вы должны указать строку формата для предиката. - person BallpointBen; 22.07.2017

Вы можете использовать строку предиката следующим образом:

@"(self ENDSWITH '.jpg') AND NOT (self ENDSWITH '@2x.jpg') AND (self BEGINSWITH '%d_photo_')"
person rob mayoff    schedule 02.08.2012
comment
Я думаю, что этот ответ намного проще, чем predicateWithBlock. Конечно, если вам нужно сделать что-то еще, предикатWithBlock — это то, что вам нужно, но просто иметь условие НЕ, строка предиката в скобках — правильное решение! - person EricWasTaken; 11.10.2015
comment
У каждого есть преимущества и недостатки. Основное преимущество моего ответа, которое не относится к ситуации с hzxu, заключается в том, что Core Data может превратить его в предложение WHERE запроса к базе данных (возможно, с использованием индекса). Core Data не может сделать это с предикатом блока. - person rob mayoff; 12.10.2015

Вы можете инкапсулировать предикат в другой предикат:

NSPredicate *positivePredicate = [NSPredicate ...];
NSPredicate *negativePredicate = [NSCompoundPredicate notPredicateWithSubpredicate: positivePredicate];

Это позволяет сохранить существующую читаемую строку формата. Обратите внимание, что с помощью NSCompoundPredicate вы также можете создавать предикаты AND и OR. Из этих трех (И, ИЛИ, НЕ) вы даже можете получить такие вещи, как предикаты XNOR и NAND (хотя, как это сделать, остается на усмотрение читателя...)

person Jonathan Grynspan    schedule 02.08.2012

Попробуй это:

NOT something ENDSWITH '@2x.jpg'
person QPenguin    schedule 01.06.2014