[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
}



답변

스위프트> = 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())

여기에 이미지 설명을 입력하십시오


답변

신속한 표준 라이브러리가 joined따르는 모든 유형의 구현 기능 Sequence(또는 프로토콜 flattenSequenceType포함하기 전에 신속한 3) Array:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = Array(numbers.joined())

경우에 따라 사용 joined()하면 새 배열 대신 게으른 컬렉션을 반환하므로 유용 할 수 있지만 Array()위 예제와 같이 이니셜 라이저로 전달 될 때 항상 배열로 변환 할 수 있습니다 .


답변

스위프트 4.x / 5.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]

이 문제를 해결하기 위해 간단한 for 루프 논리 + 재귀를 사용할 수 있습니다.

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여기 의 경우를 고려하여 모든 종류의 배열을 평평하게하는 데 도움이 됩니다

운동장 출력 :
여기에 이미지 설명을 입력하십시오


답변

스위프트 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] 


답변

편집 :joined() 대신 사용하십시오 .

https://developer.apple.com/documentation/swift/sequence/2431985-joined

원래 답변 :

let numbers = [[1, 2, 3], [4, 5, 6]]
let flattenNumbers = numbers.reduce([], combine: +)


답변

스위프트 4.2

아래에 간단한 배열 확장을 썼습니다. 다른 배열 또는 요소가 포함 된 배열을 병합하는 데 사용할 수 있습니다. joined () 메소드와는 다릅니다.

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()


답변

또 다른 더 일반적인 구현 reduce,

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let reduced = reduce(numbers,[],+)

이것은 같은 일을 수행하는데 무슨 일이 일어나고 있는지 더 많은 통찰력을 줄 수 있습니다 reduce.

애플의 문서에서

func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U

기술

이니셜시퀀스의 각 요소로 초기화 된 누적 값을 사용하여 반복적으로 결합 호출의 결과를 반환합니다 .