Make App Pie

Training for Developers and Artists

Swift Tutorial: How to Use an Array in Swift

[Updated to Swift 2.0 9/15/15 SJL]

Note: this is a Swift 2.0 version. You can find the Swift 3.0 Version of this tutorial here
Screenshot 2014-08-14 05.36.46The most important collection type is arguably the array. Arrays in Swift are simple to understand, but have a quite rich set of uses with a few new constraints compared to their Objective-C counterparts.

For those unfamiliar with arrays, arrays are an ordered collection of data.  Think of an array like a railroad train and each piece of data is a railroad car.  We refer to a specific railroad car by how many railroad cars from the front of the train a specific car is. The third car for example my be a dining car for example .  We write this as car[third] where car is the identifier of the array and third is the index.  An index is always a positive integer, and arrays in every language I can think of start with zero. That means our index is usually one less than what we expect. If we used numbers for the index, we would write car[2] for the third car for example.

Swift arrays come in two flavors: dynamic and static. Static arrays maintain their size and contents completely: after initialization no changes happen. The code cannot change the elements or the size of the array. Unlike Objective-C ‘s NSArray, which can change the value of an element, static arrays are completely static. Like any constant, static arrays use memory far more efficiently than dynamic.  Dynamic arrays allow us to change the size and contents of the array, similar to NSMutableArray in Objective-C.

Trying the Examples

For those who want to try the examples, you can open a Playground. Name it SwiftArrays. For those who don’t like playgrounds, you can also create a new single view application. In the ViewController class, you can add this code to the viewDidLoad method. Build and run to see the results. In both cases, results will be in the console. Open up the bottom pane of Xcode to see your results. I will sometimes add a print function to show the results, but not in all cases. If you wish to see a specific result, use print.

Declaring Array in Swift

Compared to Objective-C, Swift arrays are not as picky.  Swift accepts any type, not just classes in an array. Declaring static and dynamic arrays is the difference between let and var. The let declaration gives us a static array and the var a dynamic array. In both cases we set the initial values of the array in the declaration:

let myStaticArray = [
     "apple",
     "pear",
     "banana",
     "raspberry"
]
var myDynamicArray = [1,2,3,5,7,13,17,23]

Literal arrays are not limited to one physical line. Like myStaticArray, for readability you can use a separate line for each element of the array. This helps with readability of code.

Unlike Objective-C, the elements of an array must be of the same type. In the examples above, implicit typing can deduce that the static array is a string array and the dynamic is an integer array. We can declare an array of a given type by placing the element’s type in square brackets. An integer dynamic array would look like this:

var myExplicitDynamicArray:[Int] = [1,2,3,5,7,13,17,23]

If we want a empty integer dynamic array, we would declare it like this:

var myEmptyDynamicArray:[Int] = []

or this shorter form:

var myOtherEmptyArray = [Int]()

If you need an array of a certain size with the same data in each element, there is a special initializer for it:

var myVanillaArray = Array(count: 5, repeatedValue: "Vanilla")

This creates an array ["Vanilla","Vanilla","Vanilla","Vanilla","Vanilla"]

Accessing Elements in Swift

To access an element of an array, use the identifier of the array with a subscript enclosed in square brackets. The first element of the array is element 0. For example

 // access first element
myStaticArray[0]

//fourth element
myDynamicArray[3]

//add fifth element(7)
//to sixth element(13)
myDynamicArray[4] + myDynamicArray[5]

If you try to access an element outside of the array you will get a run-time error. If you had this in your code:

print(myStaticArray[10])

You would get the following error when you ran the app:
fatal error: Array index out of range
We do know the range of the array due to the count property, which gives us the number of elements in the array.

print(myStaticArray.count)

Since arrays start at zero, our last element is one less than the count. To access the last element of an array you could write:

print(myStaticArray[myStaticArray.count - 1])

Iterating Array Data in Swift

If you need to access all elements of an array we can use loops. The best for sequential access is the
for..in loop

var myArray=[1,2,3,5,7,11,13,17]
var total = 0
for element in myArray {
    print("\(element) ")
    total += element
}
print(" =  \(total)")

In line 3, the for loop, starting at the first element of the loop, sequentially gets each value for the array. This works well if you just need the value. Sometimes you need the index of the array, since the code needs multiple indexes. A variation For..in uses ranges of the index.

total = 0
for index in 1..<myArray.count{
    //add an element and the previous element together
    let sum = myArray[index] + myArray[index-1]
    total += sum
}
print(" =  \(total)")

Note two things I did here in line 3. I did not write myArray.count-1. Swift has two range operators. One ... is an full range. Had I used that, the correct code is 1...myArray.count-1 . Xcode beta 3 and later has the ..< operator. This goes one less than the top of the range. Since we use ranges to describe arrays so often, 1..<myArray.count is cleaner and more understandable code than 1...myArray.count-1. For those who get an error using ..<, you need to update Xcode to the current version.

Secondly, I started at 1 and not 0. Line four adds the current and the last array elements together. If I started at 0, I’d get an out of bounds error. Starting at 1 avoids that.

The For..in loop is the correct choice for sequential access of the array. This is most cases. There are times I want to start at the last element and go to the first element, or possibly look at every other element. For that we need a more traditional C- type loop. In a more C-type for loop we can do the following:

 // same sum as the last code using a traditional for
total = 0
for var index:Int = 1 ; index < myArray.count ;index++ {
    let sum = myArray[index] + myArray[index-1]
    total += myArray[index] + myArray[index-1]
}
print(" =  \(total)")

Line 3 initializes a variable index to 1, and then continues to loop, increasing the index by 1 as long as the index is less than myArray.count. We can count from the last element to the first this way:

//same as the last code, but counting backwards
total = 0
for var index:Int = myArray.count - 1 ; index >= 1 ;index-- {
    let sum = myArray[index] + myArray[index-1]
    total += myArray[index] + myArray[index-1]
}
print(" =  \(total)")

Here I start with a large value and loop, decrementing index until it is less than 0.

Adding and Removing Elements

To add an element to the end of the array, use the .append() method or the += operator. These two statements do the same:

    myArray = [1,2,3,5,7,11,13,17]
    myArray.append(23)
    myArray += [29]

The array [1,2,3,5,7,11,13,17] appends two numbers, changing to:  [1,2,3,5,7,11,13,17,23,29]
The advantage to the += operator is you can append another array if the elements are of the same type in both arrays.

myArray += [31, 37]

results in [1,2,3,5,7,11,13,17,23,29,31,37] In Swift, operators keep a consistency across type, which might make some traditional programmers a bit squeamish. The += in their mind is an arithmetic operator. You should not use it for arrays, only for incrementing numbers, like we did in the for loop. Swift continues such consistency with merging two arrays with the + operator

var myStringArray = ["apple","pear","banana","raspberry"]
var myOtherStringArray = ["Pepperoni","Sausage"]
var jointArray = myStringArray + myOtherStringArray

This code results in jointArray being ["apple","pear","banana","raspberry","Pepperoni","Sausage"]

To insert an element at a particular position, use the .insert(at:index) method, remembering that the first index is zero:

myArray.insert(2,atIndex:2)

This results in [1,2,2,3,5,7,11,13,17,23,29,31,37]

To change an element, assign a value to the specific element, like this:

myStringArray = ["apple","banana","raspberry"]
myStringArray[1] = "blackberry"

Will change myStringArray to ["apple","blackberry","banana","raspberry"]. You can change a range of values if both arrays are the same type.

myStringArray[1...2] = ["beagle bone","arduino"]

Will change  ["apple","blackberry","banana","raspberry"] to ["apple","beagle bone","arduino","raspberry"] . Range values specify the range to replace. You can replace with fewer items

myStringArray[1...3] = ["blackBerry", "kit kat"]

Changes elements 1,2,3 to only two elements making the array ["apple","beagle bone","arduino","raspberry"] to ["apple","blackBerry", "kit kat"]

To delete an element, there are two methods, removeAtIndex() and removeLast(). To remove the last element in the array

myStringArray.removeLast()

Changes the array to ["Apple", "BlackBerry","Raspberry","BeagleBone","Arduino"]
If we wanted to delete Blackberry or any other element but the last, we would use removeAtIndex():

myStringArray.removeAtIndex(1)

Changes the array to ["Apple","Raspberry","BeagleBone","Arduino","Kit Kat"]

When passing arrays in parameters we use the same syntax as declaring them:

func listArray(array:[Int]){
    for element in array{
        print(element)
    }
}

I could then call this function with

listArray(myArray)

Arrays Are for Classes and Types

Arrays can take any class. A common class to place into an array is a custom class for your model. For example , you might have a class to keep track of cookies

//Using arrays in a class
class Cookie{
    var name = ""
    var price = 0.00
    var rating = 0
    init(){}
    init(name:String,price:Double,rating:Int){
        self.name = name
        self.price = price
        self.rating = rating
    }
}

In your view controller, particualrly one that has a UITableView or UIPickerView, you would define an array to hold your all your cookies:

var cookie = [Cookie]()
cookie +=  [Cookie(name: "Chocolate Chip", price: 0.25, rating: 10)]
cookie += [Cookie(name: "Oatmeal", price: 0.20, rating: 5)]
cookie += [Cookie(name: "Peanut Butter", price: 0.20, rating: 4)]
cookie += [Cookie(name: "White Chocolate Macadamia", price: 0.50, rating: 10)]
cookie +=  [Cookie(name: "Butter Ganache", price: 0.35, rating: 9)]
cookie +=  [Cookie(name: "Chcocolate Cream", price: 0.22, rating: 7)]

In some function forRow access the array. For example in a picker view we could have this:

//example function -- see UIPickerView references for more detail
func pickerView(pickerView: UIPickerView,
    titleForRow row: Int,
    forComponent component: Int) -> String?{
        return cookie[row].name
}

See the post The Swift Swift Tutorial: How to Use UITableView in Swift I mentioned above for a good example of this in tables. For pickers see the post for more information about using UIPickerView.

Optionals and Array

Arrays can be used with optionals. Very often we may set an array to be optional to check for an empty state.

var optionalArray :[String]! = nil

We can also make our elements nil

var optionalElements : [String!] = [nil,"2","3","4",nil,"6"]

Going Back to the Old Arrays

As I’ve noted above, there are several differences between in Objective-C and Swift. If you like a Objective-C NSArray more than Swift’s Array type or have some legacy code to translate, you can always declare your array as one:

var myImmutableArray:NSArray! = ["x","y","2"]

Remember that NSArrays  can be nil, so  it ‘s a good idea to make it an optional like I did above. I find Objective-C arrays clunky, and will tend to avoid them if I can. Many of the API’s will bridge Swift and Objective-C without issues so there is still no need to do this, but there may be a few places where they don’t. You will need to declare an NSArray, when an array has elements of multiple classes.

Arrays are a rich, often used data structure. I had a few questions lately in comments about data structures in Swift, So I thought this might help some of them. Hope it did.

The Whole Code

//: Playground - noun: a place where people can play

import UIKit

// SwiftArrays -- A demonstration of Arrays
// In Swift 2.0

//(c)2015 Steven Lipton

//Declaring Arrays

//Literal static array
let myStaticArray = [
    "apple",
    "pear",
    "banana",
    "raspberry"
]

//literal Dynamic Array
var myDynamicArray = [1,2,3,5,7,13,17,23]

//Empty Dynamic Arrays
//Both of these work
var myEmptyDynamicArray:[Int] = []
var myOtherEmptyArray = [Int]()

//An array with the same values in all
//elements
var myVanillaArray = Array(count: 5, repeatedValue: "Vanilla")

// access first element
myStaticArray[0]

//fourth element
myDynamicArray[3]

//add fifth element(7)
//to sixth element(13)
myDynamicArray[4] + myDynamicArray[5]

//uncomment to produce runtime
// out of bounds error
//comment out  to run code.
//myDynamicArray[10]

//finding the last element with .count
myStaticArray.count
myStaticArray[myStaticArray.count - 1]

//for..in loop
var myArray=[1,2,3,5,7,11,13,17]
var total = 0
for element in myArray {
    print("\(element) ")
    total += element
}
print(" =  \(total)")


//for loop with range
total = 0
for index in 1..<myArray.count{
    //add an element and the previous element together
    let sum = myArray[index] + myArray[index-1]
    total += sum
}
print(" =  \(total)")


// same sum as the last code using a traditional for
total = 0
for var index:Int = 1 ; index < myArray.count ;index++ {
    let sum = myArray[index] + myArray[index-1]
    total += myArray[index] + myArray[index-1]
}
print(" =  \(total)")


//same as the last code, but counting backwards
total = 0
for var index:Int = myArray.count - 1 ; index >= 1 ;index-- {
    let sum = myArray[index] + myArray[index-1]
    total += myArray[index] + myArray[index-1]
}
print(" =  \(total)")

//add an element either way
myArray.append(23)
myArray += [29]

//add two elements to an array
myArray += [31, 37]


//concatenation of arrays
var myStringArray = ["apple","pear","banana","raspberry"]
var myOtherStringArray = ["Pepperoni","Sausage"]
var jointArray = myStringArray + myOtherStringArray

//insertion
myArray.insert(2,atIndex:2)

//modifying elements
myStringArray[1] = "blackberry"
myStringArray

//modifying more than one element 1:1
myStringArray[1...2] = ["beagle bone","arduino"]
myStringArray

//modfying more than one element,
// but changing less than the number of elements
myStringArray[1...3] = ["blackBerry", "kit kat"]
myStringArray

//delete last element of the array
myStringArray.removeLast()
myStringArray

//delete selected element in the array
myStringArray.removeAtIndex(1)
myStringArray


//making a function with an array as a parameter
func listArray(array:[Int]){
    for element in array{
        print(element)
    }
}
listArray(myArray)

//Using arrays in a class
class Cookie{
    var name = ""
    var price = 0.00
    var rating = 0
    init(){}
    init(name:String,price:Double,rating:Int){
        self.name = name
        self.price = price
        self.rating = rating
    }
}
// create array from a class
var cookie = [Cookie]()
cookie +=  [Cookie(name: "Chocolate Chip", price: 0.25, rating: 10)]
cookie += [Cookie(name: "Oatmeal", price: 0.20, rating: 5)]
cookie += [Cookie(name: "Peanut Butter", price: 0.20, rating: 4)]
cookie += [Cookie(name: "White Chocolate Macadamia", price: 0.50, rating: 10)]
cookie +=  [Cookie(name: "Butter Ganache", price: 0.35, rating: 9)]
cookie +=  [Cookie(name: "Chcocolate Cream", price: 0.22, rating: 7)]

//example function -- see UIPickerView references for more detail

func pickerView(pickerView: UIPickerView,
    titleForRow row: Int,
    forComponent component: Int) -> String?{
        return cookie[row].name
}

//Arrays and optionals
//optional array
var optionalArray :[String]! = nil
//optional Array elements
var optionalElements : [String!] = [nil,"2","3","4",nil,"6"]



16 responses to “Swift Tutorial: How to Use an Array in Swift”

  1. Hello,
    Every of your posts are interesting.
    I have a question regarding the buttons you wrote programmatically.
    How would be difficult to display the buttons following each other depending of the screen?
    Thanks.

    1. To avoid too much code for an array lesson, I did not mention auto layout constrains, but you can set up the array of buttons with a set of constraints programmatically. See my post https://makeapppie.com/2014/07/26/the-swift-swift-tutorial-how-to-use-uiviews-with-auto-layout-programmatically/ for how to use constraints. If using an array, set the first button with position constraints and set the others with a distance from the previous button and aligned to the previous button. If you don’t need those in an array you can still loop through the buttons with your constraints.

  2. […] an array and a dictionary is how you get the values in and out of the collection. Arrays, as we covered earlier, are ordered collections. They have an index which gives their exact place in the collection. I […]

  3. […] Swift Tutorial: How to use an Array in Swift […]

  4. […] Swift Tutorial: How to Use an Array in Swift | Making App Pie […]

  5. Hi!

    Thanks for a detailed explanation – but i’m very new to swift and programing in general – I still have a Question – I have a static array (let) that I want to take a random value from and “print” on a UILabel – What kind of dark magic do I have to do to make this?

    (i’m on the viewcontroller.swift)

    1. Good question.

      You need to do the following:
      1. Make your array
      2. Generate a random integer between 0 and array.count-1
      3. Display the array element on the label using the random integer

      So for example you might do something like this. The core part is in the displayRandom Function:
      (note I did this in a cafe away from my mac, so I’m not 100% sure about the syntax. )

      class ViewController:UIViewController{
          @IBOutlet weak var myLabel:UILabel!
          let myArray = ["Waffles","Pancakes","Eggs","Oatmeal"] 
         func displayRandom()  {  //display the random number
                 let random = Int(arc4random_uniform(myArray.count -  1))
                 myLabel.text = myArray[random]
          } 
         @IBAction func buttonPressed(sender:UIButton){
               displayRandom()               
          }
         override func viewDidLoad{
            super.viewDidLoad()
            displayRandom()
          }
      }
      
  6. Hi, thanks once again for another great lesson!

    I was wondering how to re-order an array based on another array. I have an array of unique Ints e.g [4, 1, 5, 9…] and I have an array of objects which have three properties (a question, an answer and an unique int). They both contain the same number of items.

    I want to either create a third array where these objects are in the order of the int array or re-order the object array by its unique int to match the int array.

    I tried a ‘for’ loop to do this but it just put them in numerical order rather than the order of the array.

    Any suggestions would be great! Thanks again

    1. Not sure why you are using this, but you might want to use a dictionary if you are doing what I think you are doing. See my post https://makeapppie.com/2014/08/21/the-swift-swift-tutorial-how-to-use-dictionaries-in-swift/ See if that makes for a better data structure than what you have.

  7. Hi, Thank you for the array in class example. If I add a “cookieID” to the array, how would I make a new array that only contains the customers “favorite” cookies so that I can display them in an UITableView. For example, I have an array favCookies = [4,2,5]

    1. I usually don’t write the code for these, but this is a quickie:

      var faveCookielist:[Cookie] = []
      for fave in favCookies{
          faveCookieList += cookie[fave]
      }
      
  8. […] an array and a dictionary is how you get the values in and out of the collection. Arrays, as we covered elsewhere, are ordered collections. They have an index which gives their exact place in the collection. I […]

  9. Nice tutorial. Thanks for the tips.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: