5

How to get the first N elements of array in Swift

 3 years ago
source link: https://sarunw.com/posts/how-to-get-first-n-elements-of-swift-array/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

How to get the first N elements of array in Swift

10 Dec 2020 ⋅ Swift

Using subscript with range #

Swift offers several range operators to work with the array subscript(_:). Let's say we want to retrieve the first three elements from an array. We can do that in a variety form of range operators.

Closed Range Operator

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names[0...2]
// ["Anna", "Alex", "Brian"]

Closed Range Operator with One-Sided Ranges

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names[...2]
// ["Anna", "Alex", "Brian"]

Half-Open Range Operator

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names[0..<3]
// ["Anna", "Alex", "Brian"]

Half-Open Range Operator with One-Sided Ranges

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names[..<3]
// ["Anna", "Alex", "Brian"]

All of the above examples produce the same ArraySlice of the first three items of names array. It is up to your preference to choose which form of range operator you want. I prefer a half-open range operator (0..<3) since it contains a number of elements that I want (3) to get in the range operator.

Caveats #

You might get an "Array index is out of range" error if your range is larger than an array. So, make sure your array is larger than the range or use other methods if an array size can't be determined at compile time.

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names[..<5]
// Array index is out of range
Practical Sign in with Apple

Learn everything you need to know about Sign in with Apple to be able to integrate it in your existing app or a new one.

Get it now

Using prefix(_:) #

prefix(_:) will return a subsequence, up to the specified maximum length. So if we want the first n items, we use .prefix(n).

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names.prefix(3)
// ["Anna", "Alex", "Brian"]

The great thing about this method is that you don't have to worry about indexes out of ranges like the previous example.

func prefix(_ maxLength: Int) -> ArraySlice

Since the parameter of this method is maxLength. If the maximum length exceeds the number of elements in the collection, the result contains all the elements in the collection.

We can safely use this on a collection regardless of its size.

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names.prefix(5)
// ["Anna", "Alex", "Brian", "Jack"]

Using prefix(upTo:) and prefix(through:) #

prefix(upTo:) is equivalent to using a partial half-open range as the collection’s subscript. So, the following example is equivalent to names[..<3].

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names.prefix(upTo: 3)
// ["Anna", "Alex", "Brian"]

There is also prefix(through:), which equivalent to using a partial closed range (names[...2]).

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names.prefix(through: 2)
// ["Anna", "Alex", "Brian"]

Caveats #

Apple discourages to use them. You might want to use subscript notation instead.

Apple clearly states this in the documentation pages.

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

Using the prefix(through:) method is equivalent to using a partial closed range as the collection’s subscript. The subscript notation is preferred over prefix(through:).

And since it is equivalent to subscript form, you will get the same "Array index is out of range" if your index is larger than an array. So, these methods don't add any benefit over the subscript notation.

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names.prefix(upTo: 5)
// Array index is out of range

ArraySlice #

One thing to keep in mind when using all of the above methods is, the result of them is ArraySlice. There are two things you should know about ArraySlice.

1. Slices Are Views onto Arrays #

The ArraySlice type is used as a way for us to perform operations on a subset of a larger array, which means to be fast and memory-efficient. The ArraySlice instance presents a view onto the storage of a larger array without allocating any new storage of their own.

For this reason, long-term storage of ArraySlice instances is discouraged. A slice holds a reference to the entire storage of a larger array, not just to the portion it presents, even after the original array’s lifetime ends. Long-term storage of a slice may therefore prolong the lifetime of elements that are no longer otherwise accessible, which can appear to be memory and object leakage.

If you plan to store the array slice result, please create a new array to hold that.

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names.prefix(3)
let firstThreeNames = Array(arraySlice)

2. Slices Maintain Indices of an original array #

Slices maintain the same indices of the larger array for the same elements. Unlike an array, ArraySlice may have a nonzero startIndex and an endIndex that is not equal to count since it uses the same indices of the original array.

The following example gets a slice of elements index 1 and 2 from the names array. As you can see, the index of "Alex" and "Brain" is not 0 and 1 but maintain the same indices of 1 and 2.

let names = ["Anna", "Alex", "Brian", "Jack"]
let arraySlice = names[1...2]
// ["Alex", "Brian"]
arraySlice.firstIndex(of: "Alex") // 1
arraySlice.firstIndex(of: "Brian") // 2

This might not affect our case since we try to get first N elements, but it is good to know this, so you don't blindly assume index from the ArraySlice.

Practical Sign in with Apple

Learn everything you need to know about Sign in with Apple to be able to integrate it in your existing app or a new one.

Get it now

Related Resources #


Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron

Tweet

Share

Previous
UIStackView padding

Learn how to add padding to your stack view's content.

Related Posts

Browse all content by tag

How to use UIKit in SwiftUI

Using UIView and UIViewController in SwiftUI

Swift
Sign in with Apple Tutorial, Part 3: Backend – Token verification

Part 3 in a series Sign in with Apple. In this part, we will see how backend can use the token to sign up/sign in users.

Swift
Swift Documentation

How to write documentation comments in your Swift code.

Swift

Get new posts weekly

If you enjoy this article, you can subscribe to the weekly newsletter.

Every Friday, you’ll get a quick recap of all articles and tips posted on this site — entirely for free.

← Home


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK