Сгладить массив массивов в Swift
есть ли аналог в Swift to flatten
в Scala, Xtend, Groovy, Ruby и co?
var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9]
конечно, я мог бы использовать уменьшить для этого, но это своего рода отстой
var flattened = aofa.reduce(Int[]()){
a,i in var b : Int[] = a
b.extend(i)
return b
}
7 ответов:
Swift 3.0
reduce
:let numbers = [[1,2,3],[4],[5,6,7,8,9]] let reduced = numbers.reduce([], +)
flatMap
:let numbers = [[1,2,3],[4],[5,6,7,8,9]] let flattened = numbers.flatMap { }
joined
:let numbers = [[1,2,3],[4],[5,6,7,8,9]] let joined = Array(numbers.joined())
С Swift 2.0 есть
flatten
(илиjoined
в Swift 3) Метод реализован дляCollectionType
протокол:let numbers = [[1,2,3],[4],[5,6,7,8,9]] let flattened = Array(numbers.flatten())
в некоторых случаях использование
flatten()
может быть полезным, поскольку он возвращает ленивую коллекцию вместо массива, но всегда может быть преобразован в массив при передаче вArray()
.
это сработало для меня:
let numbers = [[1, 2, 3], [4, 5, 6]] let flattenNumbers = numbers.reduce([], combine: +)
еще одна более общая реализация
reduce
,let numbers = [[1,2,3],[4],[5,6,7,8,9]] let reduced = reduce(numbers,[],+)
это делает то же самое, но может дать больше понимания того, что происходит в
reduce
.из документов Apple,
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U
описание
возвращает результат повторного вызова комбината с накопленным значением инициализируется нач и каждый элемент последовательность в свою очередь.
Swift 4.x
просто, чтобы добавить немного больше сложности в массиве, если есть массив, который содержит массив массивов, то
flatMap
на самом деле не получится.предположим, что массив
var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8]
что
flatMap
илиcompactMap
возвращает это:array.compactMap({}) //Output [1, 2, [[3, 4], [5, 6, [7]]], 8]
чтобы решить эту проблему, мы можем использовать нашу простую логику цикла + рекурсия
func flattenedArray(array:[Any]) -> [Int] { var myArray = [Int]() for element in array { if let element = element as? Int { myArray.append(element) } if let element = element as? [Any] { let result = flattenedArray(array: element) for i in result { myArray.append(i) } } } return myArray }
так что вызовите эту функцию с заданным массив
flattenedArray(array: array)
результат:
[1, 2, 3, 4, 5, 6, 7, 8]
эта функция поможет сгладить любой массив, учитывая случай
Int
здесь
переименовать flatten () в joined ().
https://github.com/apple/swift-evolution/blob/master/proposals/0133-rename-flatten-to-joined.md