Сгладить массив массивов в Swift
Есть ли копия в Swift до 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
}
Ответы
Ответ 1
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 { $0 }
joined
:
let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let joined = Array(numbers.joined())
Ответ 2
В стандартной библиотеке Swift joined
функция, реализованная для всех типов, соответствующих протоколу Sequence
(или flatten
на SequenceType
до Swift 3), который включает в себя Array
:
let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = Array(numbers.joined())
В некоторых случаях использование joined()
может быть полезным, поскольку оно возвращает ленивую коллекцию вместо нового массива, но всегда может быть преобразовано в массив при передаче в Array()
инициализатор, как в приведенном выше примере.
Ответ 3
Swift 4.x
Чтобы добавить немного сложнее в массив, если есть массив, содержащий массив массивов, то flatMap
самом деле не сработает.
Предположим, что массив
var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8]
Что возвращает flatMap
или compactMap
:
array.compactMap({$0})
//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
здесь
Выход на игровой площадке: ![enter image description here]()
Ответ 4
Это сработало для меня:
let numbers = [[1, 2, 3], [4, 5, 6]]
let flattenNumbers = numbers.reduce([], combine: +)
Ответ 5
Еще одна общая реализация 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
Описание
Возвращает результат повторного вызова объединения с накопленным значением, инициализированным начальным и каждым элементом последовательности, в свою очередь.
Ответ 6
Swift 4.x
Это использование flatMap
не считается устаревшим, и это делает для этого. https://developer.apple.com/documentation/swift/sequence/2905332-flatmap
var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatMap { $0 } //[1,2,3,4,5,6,7,8,9]
Ответ 7
Вы можете сгладить вложенный массив, используя следующий метод:
var arrays = [1, 2, 3, 4, 5, [12, 22, 32], [[1, 2, 3], 1, 3, 4, [[[777, 888, 8999]]]]] as [Any]
func flatten(_ array: [Any]) -> [Any] {
return array.reduce([Any]()) { result, current in
switch current {
case(let arrayOfAny as [Any]):
return result + flatten(arrayOfAny)
default:
return result + [current]
}
}
}
let result = flatten(arrays)
print(result)
/// [1, 2, 3, 4, 5, 12, 22, 32, 1, 2, 3, 1, 3, 4, 777, 888, 8999]
Ответ 8
Swift 4.2
Я написал простое расширение массива ниже. Вы можете использовать, чтобы сгладить массив, который содержит другой массив или элемент. в отличие от метода join().
public extension Array {
public func flatten() -> [Element] {
return Array.flatten(0, self)
}
public static func flatten<Element>(_ index: Int, _ toFlat: [Element]) -> [Element] {
guard index < toFlat.count else { return [] }
var flatten: [Element] = []
if let itemArr = toFlat[index] as? [Element] {
flatten = flatten + itemArr.flatten()
} else {
flatten.append(toFlat[index])
}
return flatten + Array.flatten(index + 1, toFlat)
}
}
использование:
let numbers: [Any] = [1, [2, "3"], 4, ["5", 6, 7], "8", [9, 10]]
numbers.flatten()
Ответ 9
Переименуйте flatten() в join().
https://github.com/apple/swift-evolution/blob/master/proposals/0133-rename-flatten-to-joined.md
Ответ 10
func convert(){
let arr = [[1,2,3],[4],[5,6,7,8,9]]
print("Old Arr = ",arr)
var newArr = [Int]()
for i in arr{
for j in i{
newArr.append(j)
}
}
print("New Arr = ",newArr)
}
![enter image description here]()