Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate a loop with index and element in Swift

Is there a function that I can use to iterate over an array and have both index and element, like Python's enumerate?

for index, element in enumerate(list):     ... 
like image 960
thinker3 Avatar asked Jun 04 '14 03:06

thinker3


People also ask

How to for loop with index in Swift?

Enumerating an array in Swift is useful when looping through arrays. Sometimes you need to know the index of each item when looping. One option is to keep track of a separate index. But this increases the code complexity—you have to keep track of a separate index and update it on each iteration.

Can you get index in for of loop?

You can access the index even without using enumerate() . Using a for loop, iterate through the length of my_list . Loop variable index starts from 0 in this case. In each iteration, get the value of the list at the current index using the statement value = my_list[index] .

How do I iterate in Swift?

In Swift, the for-in loop is used to run a block of code for a certain number of times. It is used to iterate over any sequences such as an array, range, string, etc. Here, val accesses each item of sequence on each iteration. Loop continues until we reach the last item in the sequence .


2 Answers

Yes. As of Swift 3.0, if you need the index for each element along with its value, you can use the enumerated() method to iterate over the array. It returns a sequence of pairs composed of the index and the value for each item in the array. For example:

for (index, element) in list.enumerated() {   print("Item \(index): \(element)") } 

Before Swift 3.0 and after Swift 2.0, the function was called enumerate():

for (index, element) in list.enumerate() {     print("Item \(index): \(element)") } 

Prior to Swift 2.0, enumerate was a global function.

for (index, element) in enumerate(list) {     println("Item \(index): \(element)") } 
like image 126
Cezar Avatar answered Sep 29 '22 04:09

Cezar


Swift 5 provides a method called enumerated() for Array. enumerated() has the following declaration:

func enumerated() -> EnumeratedSequence<Array<Element>> 

Returns a sequence of pairs (n, x), where n represents a consecutive integer starting at zero and x represents an element of the sequence.


In the simplest cases, you may use enumerated() with a for loop. For example:

let list = ["Car", "Bike", "Plane", "Boat"] for (index, element) in list.enumerated() {     print(index, ":", element) }  /* prints: 0 : Car 1 : Bike 2 : Plane 3 : Boat */ 

Note however that you're not limited to use enumerated() with a for loop. In fact, if you plan to use enumerated() with a for loop for something similar to the following code, you're doing it wrong:

let list = [Int](1...5) var arrayOfTuples = [(Int, Int)]()  for (index, element) in list.enumerated() {     arrayOfTuples += [(index, element)] }  print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)] 

A swiftier way to do this is:

let list = [Int](1...5) let arrayOfTuples = Array(list.enumerated()) print(arrayOfTuples) // prints [(offset: 0, element: 1), (offset: 1, element: 2), (offset: 2, element: 3), (offset: 3, element: 4), (offset: 4, element: 5)] 

As an alternative, you may also use enumerated() with map:

let list = [Int](1...5) let arrayOfDictionaries = list.enumerated().map { (a, b) in return [a : b] } print(arrayOfDictionaries) // prints [[0: 1], [1: 2], [2: 3], [3: 4], [4: 5]] 

Moreover, although it has some limitations, forEach can be a good replacement to a for loop:

let list = [Int](1...5) list.reversed().enumerated().forEach { print($0, ":", $1) }  /* prints: 0 : 5 1 : 4 2 : 3 3 : 2 4 : 1 */ 

By using enumerated() and makeIterator(), you can even iterate manually on your Array. For example:

import UIKit import PlaygroundSupport  class ViewController: UIViewController {      var generator = ["Car", "Bike", "Plane", "Boat"].enumerated().makeIterator()      override func viewDidLoad() {         super.viewDidLoad()          let button = UIButton(type: .system)         button.setTitle("Tap", for: .normal)         button.frame = CGRect(x: 100, y: 100, width: 100, height: 100)         button.addTarget(self, action: #selector(iterate(_:)), for: .touchUpInside)         view.addSubview(button)     }      @objc func iterate(_ sender: UIButton) {         let tuple = generator.next()         print(String(describing: tuple))     }  }  PlaygroundPage.current.liveView = ViewController()  /*  Optional((offset: 0, element: "Car"))  Optional((offset: 1, element: "Bike"))  Optional((offset: 2, element: "Plane"))  Optional((offset: 3, element: "Boat"))  nil  nil  nil  */ 
like image 35
Imanou Petit Avatar answered Sep 29 '22 02:09

Imanou Petit