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


179

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


의 첫 번째 요소 를 반환하는 최대 6 가지 방법을 보여주는 Swift 4에 대한 내 대답을 참조하십시오 . nArray
Imanou Petit

답변:


445

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


42
IMHO, 잘못된 이름 선택 +1 배열이 dropFirst하고 dropLast, 그래서도있을 수 있습니다 takeFirsttakeLast.
Mazyod

10
또한 first5배열 이 필요한 경우 다음과 같이 작성하십시오let first5 = Array(someArray.prefix(5))
ULazdins

2
@mluisbrown 죄송합니다, 당신에 동의하지 않습니다 :) video = video.prefix(5)Xcode 7.2의 내 프로젝트 에서 컴파일 오류가 발생합니다 Cannot assign value of type 'ArraySlice<Video>' to type '[Video]'
ULazdins

5
video = Array(video.prefix(5))
Bartłomiej Semańczyk

2
@ onmyway133 prefix은 아마도 Swift 2.x 일 것입니다 (1.x에 있는지 기억이 나지 않습니다).하지만 iOS 7 이상인 Swift 2.x를 지원하는 모든 OS에 확실히 존재합니다. Swift 기능의 가용성은 iOS 버전이 아닌 Swift 릴리스에 의해 결정됩니다.
mluisbrown

99

업데이트 : 이제 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

71
nSwift 배열 의 첫 번째 항목 만 원한다면 wholeArray.prefix(n)안전한 범위의 이점을 얻을 수 있습니다. 경우 n배열 크기보다 큰 prefix반환 전체 배열입니다.
mluisbrown

4
그것은이 경우 충돌 것 wholeArray보다 더 많은 요소를 가지고 있지 않습니다n
제이크 린

@Crashalot 나는 완전히 확신 할 수는 없지만 대답을 작성한 시점에는과 같은 것이 없었습니다 prefix.
Christian

1
이 코드를 사용하여 처음 5 개의 객체를 얻으십시오 ... 이것은 완벽하게 작동합니다. [0,1,2,3,4,5] .enumerated (). flatMap {$ 0 <5? $ 1 : nil}
Manish Mahajan

64

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"]

28
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]

18

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

3
swift3를 위해[0,1,2,3,4,5].enumerated().flatMap{ $0.offset < 1000 ? $0.element : nil }
StevenTsooo

1
감사! 업데이트하려는 경우 이제 배열 압축을 위해 flatMap을 Swift 4에서 compactMap이라고합니다.
manmal

14

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

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

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

5

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

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

3

스위프트 4

Swift 배열의 첫 번째 N 요소를 얻으려면 다음을 사용할 수 있습니다 prefix(_ maxLength: Int).

Array(largeArray.prefix(5))

1

배열 유형을 저장 한 Swift 4

extension Array {
    func take(_ elementsCount: Int) -> [Element] {
        let min = Swift.min(elementsCount, count)
        return Array(self[0..<min])
    }
}

1

신속한 4 업데이트 :

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

신속한 3 :

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

1
효과적이지 않은 솔루션. 1) 배열 길이의 추가 시퀀스를 작성합니다. 2) 모든 요소를 ​​반복합니다.
Alexander Bekert

2
10000? 그게 뭐야?
BangOperator

1

일반 및 단순

extension Array {
    func first(elementCount: Int) -> Array {
          let min = Swift.min(elementCount, count)
          return Array(self[0..<min])
    }
}

1

객체 배열의 경우 시퀀스에서 확장을 만들 수 있습니다.

extension Sequence {
    func limit(_ max: Int) -> [Element] {
        return self.enumerated()
            .filter { $0.offset < max }
            .map { $0.element }
    }
}

용법:

struct Apple {}

let apples: [Apple] = [Apple(), Apple(), Apple()]
let limitTwoApples = apples.limit(2)

// limitTwoApples: [Apple(), Apple()]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.