Предикат CoreData получает каждое предложение, которое содержит любое слово в массиве - PullRequest
0 голосов
/ 29 апреля 2018

В Swift 4 у меня есть модель CoreData «Предложение», которая имеет атрибут String «englishsentence». У меня также есть массив «слов», и я хотел бы получить все предложения, для которых атрибут «englishsentence» содержит одно или несколько слов в массиве.

var words = ["today", "yesterday", "tomorrow"]

Этот массив является лишь примером. Предполагается изменить во время выполнения и может иметь любую длину.

и в запросе на выборку я пытаюсь сделать что-то вроде этого:

let fetchRequest =
    NSFetchRequest<NSManagedObject>(entityName: "Sentence")
let predicate = NSPredicate(format: "ANY englishsentence CONTAINS ANY word IN %@", words)
    fetchRequest.predicate = predicate

Я могу создать предикат для всех предложений, содержащих одно конкретное слово. Однако я не могу заставить его работать с массивом слов, если, конечно, я не переберу массив слов и сделаю новый запрос на выборку для каждого отдельного слова. Но это кажется ужасно неэффективным.

1 Ответ

0 голосов
/ 29 апреля 2018

Один из вариантов - создать «составной предикат»:

let words = ["today", "yesterday", "tomorrow"]

let predicates = words.map {
    NSPredicate(format: "englishsentence CONTAINS %@", $0)
}
let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)

Другим вариантом является сопоставление с регулярным выражением:

let regex = ".*(" + words.map {
    NSRegularExpression.escapedPattern(for: $0)
}.joined(separator: "|") + ").*"

let predicate = NSPredicate(format: "englishsentence MATCHES %@", regex)

Чтобы соответствовать только «целым словам», вы можете добавить шаблон границы слова \b:

let regex = ".*\\b(" + words.map {
    NSRegularExpression.escapedPattern(for: $0)
}.joined(separator: "|") + ")\\b.*"
...