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 отфильтрует их по выбранным идентификаторам.

Другие вопросы по тегам