Swift 4 - Фильтрация массива с помощью массива
У меня есть список записей с идентификатором, и я хочу отфильтровать их до записей с идентификатором entry.id, соответствующим одному из идентификаторов в selectedID. Есть ли способ сделать это с помощью фильтра или я должен использовать цикл for?
struct Entry {
let id: String
}
var allEntries = [Entry]()
var selectedIDs = [String]
например
allEntries = [Entry(id: "1"), Entry(id:"2"), Entry(id:"3"), Entry(id:"4")]
selectedIDs = ["1", "3"]
// return selectedEntries
var selectedEntries = [Entry(id: "1"), Entry(id: "3")]
4 ответа
Нет ничего плохого в ответе Ракешы Шастри. По соображениям производительности, вы можете сделать selectedIDs
Set
вместо Array
:
let allEntries = [Entry(id: "1"), Entry(id:"2"), Entry(id:"3"), Entry(id:"4")]
let selectedIDs: Set<String> = ["1", "3"]
let selectedEntries = allEntries.filter({ selectedIDs.contains($0.id) })
Причина в том, что поиск Array
имеет вычислительную сложность O(n)
где n
длина массива при поиске Set
(т.е. хеш-таблица) O(1)
в среднем.
Если вы продолжаете
selectedIDs
как массив, общее решение имеет сложностьO(n * m)
гдеn
а такжеm
длиныselectedIDs
а такжеallEntries
соответственно.Если вы используете
Set
общая сложность сводится кO(m)
,
Сказав это, ваш пример слишком тривиален, чтобы оба метода могли что-то изменить.
Фильтр allEntries
в зависимости от того selectedIDs
содержит id
,
var allEntries = [Entry(id: "1"), Entry(id:"2"), Entry(id:"3"), Entry(id:"4")]
var selectedIDs = ["1", "3"]
var selectedEntries = allEntries.filter({ selectedIDs.contains($0.id) })
Свифт 5.5:
let filteredArray = array.filter { self.selectedIDs.map(\.id).contains($0.id) }
Вы можете использовать карту (:) и фильтр (:) для достижения этой цели
let matchingEntries = allEntries.map({$0.id}).filter({selectedIDs.contains($0)})
.map вернет вам только идентификаторы в виде массива, а затем .filter отфильтрует их по выбранным идентификаторам.