Разница между flatMap и compactMap в Swift
похоже, что в Swift 4.1 flatMap
устарела. Однако есть новый метод в Swift 4.1 compactMap
который делает то же самое?
С flatMap
вы можете преобразовать каждый объект в коллекции, а затем удалить все элементы, которые были нулевыми.
как flatMap
let array = ["1", "2", nil]
array.flatMap { } // will return "1", "2"
как compactMap
let array = ["1", "2", nil]
array.compactMap { } // will return "1", "2"
compactMap
делает то же самое.
каковы различия между эти 2 метода? Почему Apple решила переименовать метод?
2 ответов
существует три различных варианта flatMap. Вариант Sequence.flatMap(_:)
, который принимает закрытие, возвращающее необязательное значение, устарел. Другие варианты flatMap (_:) как для последовательности, так и для опции остаются как есть. Причина, как поясняется в документе предложения, заключается в неправильном использовании.
устаревший flatMap
функциональность варианта точно такая же при новом методе compactMap
.
подробности здесь.
стандартная библиотека Swift определяет 3 перегрузки для flatMap
функция:
Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element]
Optional.flatMap<U>(_: (Wrapped) -> U?) -> U?
Sequence.flatMap<U>(_: (Element) -> U?) -> [U]
последняя функция перегрузки может использоваться двумя способами:
Рассмотрим следующую структуру и массив:
struct Person {
var age: Int
var name: String
}
let people = [Person(age: 21, name: "Osame"), Person(age: 17, name: "Masoud"), Person(age: 20, name: "Mehdi")]
Первый способ: дополнительная упаковка и разворачивание:
Если вам нужно получить массив возрастов лиц, включенных в people
array вы можете использовать две функции:
let flatMappedAges = people.flatMap({.age}) // prints: [21, 17, 20]
let mappedAges = people.map({.age}) // prints: [21, 17, 20]
в этом случае будет делать работа и нет необходимости использовать flatMap
, потому что оба дают один и тот же результат. Кроме того, в этом случае использования flatMap есть бесполезный процесс упаковки и разворачивания.(Параметр closure обертывает возвращаемое значение необязательным, а реализация flatMap разворачивает необязательное значение перед его возвращением)
Второй способ-соответствие строки протоколу сбора:
Думаю, вам нужно получить список имен людей из people
массив. Вы можно использовать следующую строку :
let names = people.flatMap({.name})
если вы используете версию swift до 4.0, вы получите преобразованный список
["Osame", "Masoud", "Mehdi"]
но в более новых версиях String
соответствует Collection
протокол, Итак, ваше использование flatMap()
будет соответствовать первой функции перегрузки вместо третьей и даст вам сплющенный результат ваших преобразованных значений:
["O", "s", "a", "m", "e", "M", "a", "s", "o", "u", "d", "M", "e", "h", "d", "i"]
заключение: они устарели третью перегрузку flatMap ()
Из-за этих злоупотреблений команда swift решила отказаться от третьей перегрузки функции flatMap. И их решение в том случае, когда вам нужно разобраться с Optional
s до сих пор должен был ввести новую функцию под названием compactMap()
что даст вам ожидаемый результат.