Сравнение строк с NSPredicate перед сохранением в Core Data

Я пытаюсь выполнить сравнение строк перед сохранением в Core Data.

Строка, которая будет сохранена в Core Data, будет содержать список физических упражнений. Цепочка упражнений должна быть сохранена только один раз независимо от порядка.

Пример:

let str1 = "Burpees Rowing Running"
// This is in Core Data

let str2 = "Running Rowing Burpees"
// This is an attempt to save to Core Data. It should *fail* because there is already an exercise set with these exercises - just not in the same order.

Мой прогресс:

func checkEntityThenSave(exerciseGroup:String){
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "SavedExerciseSets")
    let predicate = NSPredicate(format: "upperBody.sortedComponents == %@", exerciseGroup.components(separatedBy: " ").sorted())
    
    request.predicate = predicate
    request.fetchLimit = 1

    do{
        let count = try context.count(for: request)
        
        print("Count - \(count)") // Always evaluates to 0

        if(count > 0){
            // Save to Core Data
        }
        else{
            // Show Alert
        }
      }
    catch let error as NSError {
        print("Could not fetch \(error), \(error.userInfo)")
    }
}

В своем коде я пытаюсь сравнить полученный результат (строку) в Core Data с новой строкой, которую я пытаюсь сохранить.

Моя проблема в том, что я продолжаю получать 0, что приводит к сбою попытки сохранения каждый раз.

Как сравнить строку, которую я пытаюсь сохранить, со строкой, которая встречается в Core Data?


person Joe    schedule 01.04.2021    source источник
comment
Это похоже на результат не очень оптимального дизайна, почему упражнения в строке вместо того, чтобы быть их собственной сущностью?   -  person Joakim Danielson    schedule 01.04.2021
comment
Если вы не хотите менять дизайн, я не вижу другого пути, кроме как разделить входную строку и создать набор из результата, а затем загрузить все объекты из Core Data и таким же образом преобразовать upperBody в массив Set, а затем проверьте, существует ли первый набор в этом массиве.   -  person Joakim Danielson    schedule 01.04.2021
comment
SavedExerciseSets содержит несколько других атрибутов. upperBody — единственный атрибут, который мне нужно проверить перед сохранением модели в SavedExerciseSets. Не знаю, зачем мне нужно разбивать его на отдельные сущности.   -  person Joe    schedule 02.04.2021
comment
Потому что это правильно с точки зрения дизайна, IMO, но вы всегда можете выбрать другое предложенное мной решение или решение, предложенное ниже.   -  person Joakim Danielson    schedule 02.04.2021
comment
Действительно ли SavedExerciseSets, существующий в ваших CoreData, "Running Rowing Burpees"? Я имею в виду со всеми заглавными буквами в начале каждого слова?   -  person Larme    schedule 04.04.2021
comment
@ Ларме Да. Все они в верхнем регистре.   -  person Joe    schedule 04.04.2021
comment
Имеет ли ваша сущность upperBody атрибут sortedComponents, то есть отсортированный массив строк? Если это так, ваш код должен работать, иначе нет, потому что SQL не может разложить и отсортировать строковые атрибуты перед выборкой.   -  person Reinhard Männer    schedule 04.04.2021


Ответы (1)


Предполагая, что ваш sortedComponents имеет тип String, возможно, вы можете попробовать это:

let sortedExerciseGroup = exerciseGroup.components(separatedBy: " ").sorted().joined(separator: " ")
let predicate = NSPredicate(format: "upperBody.sortedComponents == %@", sortedExerciseGroup)

Но если ваш sortedComponents имеет тип [String], код в вопросе уже должен работать, просто убедитесь, что вы сохранили в основных данных уже отсортированный exerciseGroup.

person ramacode    schedule 05.04.2021
comment
просто убедитесь, что вы сохранили в основных данных уже отсортированную группу упражнений. Это был ключ!! Большое спасибо @ramacode. Я явно пропустил этот шаг :) - person Joe; 05.04.2021
comment
Ха-ха, добро пожаловать! Следует добавить сохранение в реализацию основных данных в вопросе. Тем не менее, рад, что вы решили проблему! - person ramacode; 06.04.2021