Найдите объекты, которые включают массив, содержащий все элементы второго массива - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь отфильтровать набор объектов на основе значений в одном из их элементов на основе другого массива. У меня он отлично работает с фильтром, если поиск - "ИЛИ" - он возвращает все объекты, для которых найдена хотя бы одна из строк в массиве поиска.

Но я не могу выяснить, как заставить его работать как поиск И - возвращая только те объекты, которые соответствуют ВСЕМ строкам в массиве поиска.

Пример:

struct Schedule {
    let title: String
    let classTypes: [String]
}

let schedule1 = Schedule(title: "One", classTypes: ["math","english","chemistry","drama"])
let schedule2 = Schedule(title: "Two", classTypes: ["pe","math","biology"])
let schedule3 = Schedule(title: "Three", classTypes: ["english","history","math","art"])

let schedules = [schedule1, schedule2, schedule3]

let searchArray = ["math", "english"]

//works for OR - "math" or "english"
var filteredSchedules = schedules.filter { $0.classTypes.contains(where: { searchArray.contains($0) }) }

Я хотел бы найти способ использовать тот же массив поиска

let searchArray = ["math", "engli sh"]

Но возвращать только элементы 1 и 3 - поскольку у них обоих есть ОБА математика и английский sh в списке.

Есть хорошие примеры условий И, когда И используется для разных критериев поиска: тип и цвет автомобиля - но Мне не удалось найти пример, в котором критерии динамически основаны на элементах в массиве. Для контекста у меня могут быть десятки расписаний с более чем 20 типами классов.

1 Ответ

1 голос
/ 13 июля 2020

Вы можете работать с Set, isSubset вернет true, если элемент расписаний содержит все элементы searchSet

let searchSet = Set(searchArray)
var filteredSchedules = schedules.filter { searchSet.isSubset(of: $0.classTypes) }

Согласно предложению @LeoDabus, возможно, стоит изменить тип classTypes на Устанавливается вместо массивов (если порядок не имеет значения), поскольку они кажутся уникальными, и тогда фильтрация может выполняться противоположным образом без необходимости каждый раз преобразовывать searchArray

var filteredSchedules = schedules.filter { $0.classTypes.isSuperset(of: searchArray) }
...