Как можно быстро сгладить массив в Swift?
Я хочу включить это:
let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
в это:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
очень изящно.
Самый простой способ, конечно,
var y = [Int]()
x.forEach { y.appendContentsOf($0) }
Но это делает результирующий массив изменчивым, что необязательно. Мне это не нравится.
Я попытался использовать reduce
:
let y = x.reduce([Int]()) { (array, ints) -> [Int] in
array.appendContentsOf(ints)
return array
}
Но компилятор жалуется, что array
является неизменным, поэтому я не могу вызвать метод мутации appendContentsOf
.
Следовательно, я добавил некоторые вещи:
let y = x.reduce([Int]()) { (array, ints) -> [Int] in
var newArr = array
newArr.appendContentsOf(ints)
return newArr
}
Это просто плохо. У меня есть инстинкт о том, что это не экономно.
Как я могу сгладить массив более быстро, чем описанные выше методы? Один лайнер был бы хорош.
Ответы
Ответ 1
Здесь есть встроенная функция joined
:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].joined()
(Обратите внимание, что это фактически не возвращает другой массив, он возвращает FlattenBidirectionalCollection
, но это обычно не имеет значения, поскольку это еще последовательность, которую вы можете использовать с циклами for
и еще что-то., вы можете использовать Array(arrayOfArrays.joined())
.)
Функция flatMap
также может помочь вам. Его подпись, грубо говоря,
flatMap<S: SequenceType>(fn: (Generator.Element) -> S) -> [S.Generator.Element]
Это означает, что вы можете передать fn
, который для любого элемента возвращает последовательность, и он будет объединять/объединять эти последовательности.
Так как ваши элементы массива сами являются последовательностями, вы можете использовать функцию, которая просто возвращает сам элемент ({ x in return x }
или эквивалентно просто {$0}
):
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].flatMap{ $0 }
Ответ 2
В Swift 5 вы можете выбрать один из трех следующих способов, чтобы сгладить массив.
# 1. Свести массив с flatMap(_:)
метода Array
flatMap(_:)
В Swift типы, соответствующие протоколу Sequence
(включая Array
), имеют flatMap(_:)
. Array
flatMap(_:)
имеет следующее объявление:
func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
Возвращает массив, содержащий объединенные результаты вызова данного преобразования с каждым элементом этой последовательности.
Пример кода Playground ниже показывает, как сгладить Array
типа [[Int]]
для типа [Int]
используя flatMap(_:)
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.flatMap({ (element: [Int]) -> [Int] in
return element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 2. Свести массив с помощью метода Array
joined()
Array
есть метод joined()
. joined()
имеет следующее объявление:
func joined() -> FlattenSequence<Array<Element>>
Возвращает элементы этой последовательности последовательностей, сцепленные.
В следующем примере кода Playground показано, как сгладить Array
типа [[Int]]
для типа [Int]
с помощью joined()
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenCollection = array.joined()
let flattenArray = Array(flattenCollection)
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 3. Выровнять массив с помощью метода reduce(_:_:)
Array
reduce(_:_:)
Swift Array
имеет метод reduce(_:_:)
со следующим объявлением:
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
Возвращает результат объединения элементов последовательности с использованием данного замыкания.
В следующем примере кода Playground показано, как сгладить Array
типа [[Int]]
чтобы ввести [Int]
используя reduce(_:_:)
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce([], { (result: [Int], element: [Int]) -> [Int] in
return result + element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
В качестве альтернативы reduce(_:_:)
, вы можете использовать reduce(into:_:)
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce(into: [Int]()) { (result: inout [Int], element: [Int]) in
result += element
}
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
Ответ 3
Функция сглаживания в массиве:
let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let y = Array(x.flatten())
print(y)
функция flatMap в массиве:
let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let y = x.flatMap({$0})
print(y)
Ваш результат:
![введите описание изображения здесь]()
Подробнее: Массив в Swift