Подтвердить что ты не робот

Сгладить массив массивов в 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
}
4b9b3361

Ответ 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

Описание

Возвращает результат повторного вызова объединения с накопленным значением, инициализированным начальным и каждым элементом последовательности, в свою очередь.

Ответ 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()

Ответ 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