Я пытаюсь отфильтровать свои данные json по идентификаторам (пытаясь отметить некоторые избранные и отфильтровать их, используя их)
struct workoutList : Codable {
let id : Int
let title : String
let tag : String
}
func selectedWorkoutGroup(libraryFilter: Int, jsonErgWorkouts:[workoutList], workoutGroupBox: UITextField) -> [workoutList] {
var selectedGroup = [workoutList]()
let workoutFav = [1,10,100]
if libraryFilter == 0 {
// This works because I'm filtering based on 1 specific item
selectedGroup = jsonErgWorkouts.filter { $0.tag == workoutGroupBox.text }
} else if libraryFilter == 1 {
// Here I want to filter and show only the favorites
selectedGroup = jsonErgWorkouts.filter { $0.id } //
print("selectedGroup:\(selectedGroup)")
}
return selectedGroup
}
в приведенном выше коде фильтр работает, когда у меня есть 1 (один) какой-то конкретный элемент для фильтрации, а затем я получаю весь массив json с этим тегом.
Теперь я хочу реализовать список избранного, в котором пользователь выбирает, например, ID == [1, 10, 100] в качестве своего избранного.
Как я могу использовать команду фильтра, чтобы сделать это? Я пробовал несколько вещей и искал через SO (но не работает). Большинство ответов основаны на фильтрации по конкретным элементам, например:
selectedGroup = jsonErgWorkouts.filter { workoutFav?.contains($0.id) }
редактировать: (опущено, что я использую/сохраняю избранное в userDefaults. Этот код дает ошибку типа выражения неоднозначно без дополнительного контекста
func selectedWorkoutGroup(libraryFilter: Int, jsonErgWorkouts:[workoutList], workoutGroupBox: UITextField) -> [workoutList] {
var selectedGroup = [workoutList]()
UserDefaults.standard.set([1,10,100], forKey: "workoutFavorite")
/// This one gets stored as [Any] so I cast it to [Int]
let workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int]
if libraryFilter == 0 {
// This works because I'm filtering based on 1 specific item
selectedGroup = jsonErgWorkouts.filter { $0.tag == workoutGroupBox.text }
} else if libraryFilter == 1 {
selectedGroup = workoutFav.flatMap { favouriteId in // for each favourite ID
jsonErgWorkouts.filter { $0.id == favouriteId } // This returns Error "type of expression is ambiguous without more context"
} // flatMap joins all those arrays returns by "filter" together, no need to do anything else
print("selectedGroup:\(selectedGroup)")
}
return selectedGroup
}
Окончательное решение: переход от этого
let workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int]
to This (обратите внимание на as! вместо as?)
let workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as! [Int]
работает с использованием ответа @sweeper. Спасибо
Обновление: выяснено, почему возникла эта ошибка. Тип выражения неоднозначен без дополнительного контекста при преобразовании вывода UserDefaults as? [Int]
и должен был использовать as! [Int]
Но использование принудительной развертки as! [Int]
приводит к сбою приложения, если у пользователя не было избранного, сохраненного в UserDefault. (Что мне затем пришлось кодировать), как показано ниже.
var workoutFav = [Int]()
if !(UserDefaults.standard.array(forKey: "workoutFavorite") == nil) {
workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as! [Int]
}
Затем это было упрощено и удалено принудительное развертывание на основе этого SO стать этой однострочной
let workoutFav = UserDefaults.standard.array(forKey: "workoutFavorite") as? [Int] ?? [Int]()