Swiftで配列の最初の5つのオブジェクトを返す方法は?


178

Swiftで、配列の高次メソッドを使用して最初の5つのオブジェクトを返す賢い方法はありますか?それを行うobj-cの方法は、インデックスを保存し、インデックスが5になるまでインデックスをインクリメントしてループし、新しい配列を返すことでした。これを行う方法はありますかfiltermapまたはreduce


の最初の要素を返す最大6つの異なる方法を示すSwift 4に対する私の回答を参照しください。nArray
Imanou Petit 2017

回答:


441

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パラメーターを期待しているメソッドに渡す必要がある場合は、結果を型に強制する必要がありますArraylet first5 = Array(someArray.prefix(5))


41
そんな悪い名前の選択を+1してください。アレイはありdropFirstdropLast、とても同様かもしれないtakeFirsttakeLast
Mazyod 2015年

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))
パルトロミエSemańczyk

2
@ onmyway133 prefixはSwift 2.xのみである可能性があります(1.xであったかどうかは覚えていません)が、iOS 7以上のSwift 2.xをサポートするすべてのOSに確かに存在します。Swift機能を利用できるかどうかは、iOSバージョンではなく、Swiftリリースによって決まります。
mluisbrown 2016

99

更新:prefix配列の最初のn個の要素を取得するため に使用できるようになりました。接頭辞の使用方法の説明については、@ mluisbrownの回答を確認してください。

元の回答: なしでfiltermapまたは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 2015

4
wholeArray要素数がこれより多くない場合はクラッシュしますn
Jake Lin

@Crashalot完全に定かではありませんが、私が答えを書いた当時は、のようなものはなかったと思いますprefix
クリスチャン

1
このコードを使用して最初の5つのオブジェクトを取得します...これは完全に機能します [0,1,2,3,4,5] .enumerated()。flatMap {$ 0 <5?$ 1:nil}
マニッシュマハジャン

64

Swift 5では、必要に応じて、問題を解決するために6つのPlaygroundコードのいずれかを選択できます。


#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(_:)

最大長がコレクション内の要素数を超える場合、結果にはコレクション内のすべての要素が含まれます。


#3。使用する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

SWIFT 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
for swift3[0,1,2,3,4,5].enumerated().flatMap{ $0.offset < 1000 ? $0.element : nil }
StevenTsooo

1
ありがとう!更新したい場合に備えて、Swift 4では配列の圧縮のためにflatMapが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

Swift 4の更新:

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

Swift 3の場合:

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

1
効果のないソリューション。1)配列の長さの追加シーケンスを作成します。2)すべての要素を繰り返し処理します。
Alexander Bekert

2
10000?あれは何でしょう?
BangOperator 2018年

1

シンプルでシンプル

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

1

オブジェクトの配列の場合、Sequenceから拡張を作成できます。

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.