[arrays] Swift에서 Array의 처음 5 개 객체를 반환하는 방법은 무엇입니까?

Swift에는 Array에서 고차 메서드를 사용하여 5 개의 첫 번째 객체를 반환하는 영리한 방법이 있습니까? obj-c 방식으로 인덱스를 저장하고 배열 증가 인덱스를 5가 될 때까지 for-loop하고 새 배열을 반환했습니다. 이 할 수있는 방법이 있나요 filter, map또는 reduce?



답변

Swift 배열의 첫 번째 N 요소를 얻는 가장 먼 방법은 prefix(_ maxLength: Int)다음과 같습니다.

let someArray = [1, 2, 3, 4, 5, 6, 7]
let first5 = someArray.prefix(5) // 1, 2, 3, 4, 5

이것은 경계가 안전하다는 이점이 있습니다. 전달하는 개수 prefix가 배열 개수보다 크면 전체 배열 만 반환합니다.

참고 : 주석에서 지적했듯이 Array.prefix실제로는 ArraySlice아닌을 반환 합니다 Array. 대부분의 경우 이것은 차이가 없어야하지만 결과를 Array형식 에 할당 하거나 Array매개 변수를 기대하는 메서드에 전달 해야하는 경우 결과를 Array형식 으로 강제 설정해야 합니다.let first5 = Array(someArray.prefix(5))


답변

업데이트 :
이제 prefix배열의 처음 n 개 요소를 얻는 데 사용할 수 있습니다. 접두사를 사용하는 방법에 대한 설명은 @mluisbrown의 답변 을 확인하십시오 .

원래 답변 :
당신은 정말 쉽습니다없이 할 수있는 filter, map또는 reduce당신의 배열의 범위를 반환하여 :

var wholeArray = [1, 2, 3, 4, 5, 6]
var n = 5

var firstFive = wholeArray[0..<n] // 1,2,3,4,5


답변

Swift 5를 사용하면 필요에 따라 다음 6 가지 놀이터 코드 중 하나를 선택 하여 문제를 해결할 수 있습니다.


#1. subscript(_:)아래 첨자 사용

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array[..<5]
//let arraySlice = array[0..<5] // also works
//let arraySlice = array[0...4] // also works
//let arraySlice = array[...4] // also works
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

# 2. prefix(_:)방법을 사용하여

복잡성 : O (1) 모음이 다음을 준수하는 경우 RandomAccessCollection; 그렇지 않으면 O ( k ), 여기서 k 는 컬렉션의 시작 부분에서 선택할 요소의 수입니다.

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

애플에 대한 상태 prefix(_:):

최대 길이가 컬렉션의 요소 수를 초과하면 컬렉션의 모든 요소가 결과에 포함됩니다.


#삼. prefix(upTo:)방법을 사용하여

복잡성 : O (1)

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(upTo: 5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

애플에 대한 상태 prefix(upTo:):

prefix(upTo:)방법을 사용하는 것은 부분 반 개방 범위를 컬렉션의 첨자로 사용하는 것과 같습니다. 아래 첨자 표기법이보다 선호됩니다 prefix(upTo:).


# 4. prefix(through:)방법을 사용하여

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(through: 4)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

# 5. removeSubrange(_:)방법을 사용하여

복잡도 : O ( n ), 여기서 n 은 모음의 길이입니다.

var array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
array.removeSubrange(5...)
print(array) // prints: ["A", "B", "C", "D", "E"]

# 6. dropLast(_:)방법을 사용하여

복잡성 : O (1) 모음이 다음을 준수하는 경우 RandomAccessCollection; 그렇지 않으면 O ( k ). 여기서 k는 제거 할 요소의 수입니다.

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let distance = array.distance(from: 5, to: array.endIndex)
let arraySlice = array.dropLast(distance)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]


답변

let a: [Int] = [0, 0, 1, 1, 2, 2, 3, 3, 4]
let b: [Int] = Array(a.prefix(5))
// result is [0, 0, 1, 1, 2]


답변

스위프트 4

다른 해결책 :

어레이가 너무 짧은 경우에도 충돌하지 않는 간편한 인라인 솔루션

[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 3 ? $0.element : nil }

그러나 이것으로 잘 작동합니다.

[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 1000 ? $0.element : nil }

이 작업을 수행하면 일반적으로 충돌이 발생합니다.

[0,1,2,3,4,5].prefix(upTo: 1000) // THIS CRASHES

[0,1,2,3,4,5].prefix(1000) // THIS DOESNT


답변

배열의 처음 5 개 요소를 가져 오려면 해당 배열을 슬라이스하기 만하면됩니다. Swift에서는 다음과 같이합니다 array[0..<5].

배열의 N 번째 첫 번째 요소를 좀 더 기능적이고 일반화 할 수 있도록 확장 방법을 만들 수 있습니다. 예를 들어 :

extension Array {
    func takeElements(var elementCount: Int) -> Array {
        if (elementCount > count) {
            elementCount = count
        }
        return Array(self[0..<elementCount])
    }
}


답변

var메소드 선언 내부는 더 이상 지원되지 않으므로 Markus의 답변을 최신 Swift 버전으로 업데이트하도록 약간 변경했습니다 .

extension Array {
    func takeElements(elementCount: Int) -> Array {
        if (elementCount > count) {
            return Array(self[0..<count])
        }
        return Array(self[0..<elementCount])
    }
}