[arrays] How to return first 5 objects of Array in Swift?

In Swift, is there a clever way of using the higher order methods on Array to return the 5 first objects? The obj-c way of doing it was saving an index, and for-loop through the array incrementing index until it was 5 and returning the new array. Is there a way to do this with filter, map or reduce?

This question is related to arrays swift

The answer is


Swift 4

To get the first N elements of a Swift array you can use prefix(_ maxLength: Int):

Array(largeArray.prefix(5))

With Swift 5, according to your needs, you may choose one of the 6 following Playground codes in order to solve your problem.


#1. Using subscript(_:) 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. Using prefix(_:) method

Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(k), where k is the number of elements to select from the beginning of the collection.

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

Apple states for prefix(_:):

If the maximum length exceeds the number of elements in the collection, the result contains all the elements in the collection.


#3. Using prefix(upTo:) method

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

Apple states for prefix(upTo:):

Using the prefix(upTo:) method is equivalent to using a partial half-open range as the collection's subscript. The subscript notation is preferred over prefix(upTo:).


#4. Using prefix(through:) method

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. Using removeSubrange(_:) method

Complexity: O(n), where n is the length of the collection.

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. Using dropLast(_:) method

Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(k), where k is the number of elements to drop.

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

Update for swift 4:

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

For swift 3:

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

For an array of objects you can create an extension from Sequence.

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

Usage:

struct Apple {}

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

// limitTwoApples: [Apple(), Apple()]

SWIFT 4

A different solution:

An easy inline solution that wont crash if your array is too short

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

But works fine with this.

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

Usually this would crash if you did this:

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

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

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]

Plain & Simple

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

I slightly changed Markus' answer to update it for the latest Swift version, as var inside your method declaration is no longer supported:

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

The Prefix function is definitely the most efficient way of solving this problem, but you can also use for-in loops like the following:

let array = [1,2,3,4,5,6,7,8,9]
let maxNum = 5
var iterationNumber = 0
var firstNumbers = [Int()]
if array.count > maxNum{
  for i in array{
    iterationNumber += 1
    if iterationNumber <= maxNum{
      firstNumbers.append(i)
    }
  }
  firstNumbers.remove(at: 0)
  print(firstNumbers)
} else {
  print("There were not \(maxNum) items in the array.")
}

This solution takes up many lines of code but checks to see if there are enough items in the array to carry out the program, then continues and solves the problem. This solution uses many basic functions including array.count, which returns the amount of items in the array, not the position of last item in the array. It also uses array.append, which adds things onto the end of the array. Lastly, it uses array.remove, which removes the array's item that has a specified position.

I have tested it it and it works for at least swift 5.


For getting the first 5 elements of an array, all you need to do is slice the array in question. In Swift, you do it like this: array[0..<5].

To make picking the N first elements of an array a bit more functional and generalizable, you could create an extension method for doing it. For instance:

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

Update: There is now the possibility to use prefix to get the first n elements of an array. Check @mluisbrown's answer for an explanation how to use prefix.

Original Answer: You can do it really easy without filter, map or reduce by just returning a range of your array:

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

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

Swift 4 with saving array types

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