Компилятор недостаточно умен, чтобы понимать функции стандартной библиотеки и предлагать способы оптимизации их вызовов.
Однако проблема цепочки не в двойной итерации.С точки зрения производительности итерация не является большой проблемой.Настоящая проблема - последствия для памяти.Каждый раз, когда вы вызываете .filter
или .map
, результатом является новая последовательность, поэтому нам нужна память для хранения временной последовательности.
Чтобы слиться с этим, массивы Swift имеют .lazy свойство, которое позволяет лениво связывать, без создания промежуточных результатов и без нескольких итераций:
bookResults.books
.lazy
.filter { !$0.pictures.isEmpty }
.map { ... }
В качестве другого решения вы всегда можете объединить filter
и map
, используя compactMap
:
let presentableBooks = bookResults.books
.compactMap { book in
guard let image = book.pictures.first else { return nil }
return SearchBooks.Search.Response.BookPresentable(
pictureKey: image,
pictureStatus: .downloading,
name: book.name,
price: book.price
)
}