Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating through all but the last index of an array

Tags:

swift

swift3

I understand that in Swift 3 there have been some changes from typical C Style for-loops. I've been working around it, but it seems like I'm writing more code than before in many cases. Maybe someone can steer me in the right direction because this is what I want:

let names : [String] = ["Jim", "Jenny", "Earl"]
for var i = 0; i < names.count - 1; i+=1 {
    NSLog("%@ loves %@", names[i], names[i+1])
}

Pretty simple stuff. I like to be able to get the index I'm on, and I like the for-loop to not run if names.count == 0. All in one go.

But it seems like my options in Swift 3 aren't allowing me this. I would have to do something like:

let names : [String] = ["Jim", "Jenny", "Earl"]
if names.count > 0 {
    for i in 0...(names.count - 1) {
        NSLog("%@ loves %@", names[i], names[i+1])
    }
}

The if statement at the start is needed because my program will crash in the situation where it reads: for i in 0...0 { }

I also like the idea of being able to just iterate through everything without explicitly setting the index:

// Pseudocode
for name in names.exceptLastOne {
    NSLog("%@ loves %@", name, name.plus(1))
}

I feel like there is some sort of syntax that mixes all my wants, but I haven't come across it yet. Does anyone know of a way? Or at least a way to make my code more compact?

UPDATE: Someone suggested that this question has already been asked, citing a SO post where the solution was to use something to the degree of:

for (index, name) in names.enumerated {}

The problem with this when compared to Hamish's answer is that I only am given the index of the current name. That doesn't allow me to get the value at index without needing to do something like:

names[index + 1]

That's just one extra variable to keep track of. I prefer Hamish's which is:

for i in names.indices.dropLast() {
    print("\(names[i]) loves \(names[i + 1])")
}

Short, simple, and only have to keep track of names and i, rather than names, index, and name.

like image 265
Kjell Avatar asked Dec 04 '16 23:12

Kjell


People also ask

How do you get the last index of a string array?

lastIndexOf() The lastIndexOf() method returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backwards, starting at fromIndex .

How do you check if an element is the last element of an array?

1) Using the array length property The length property returns the number of elements in an array. Subtracting 1 from the length of an array gives the index of the last element of an array using which the last element can be accessed.

Which index is the last element in an array called at?

The key insight here is that, in one-based indexing, the index of the last item is the length of the array. If the array has a length of 3, you know that the last element in the array has an index of 3 .

How do you traverse the last element of a list in Python?

Get the last element of the list using the “length of list - 1” as an index and print the resultant last element of the list. Get the last element of the list using − 1(negative indexing) as the index and print the resultant last element of the list.


1 Answers

One option would be to use dropLast() on the array's indices, allowing you to iterate over a CountableRange of all but the last index of the array.

let names = ["Jim", "Jenny", "Earl"]

for i in names.indices.dropLast() {
    print("\(names[i]) loves \(names[i + 1])")
}

If the array has less than two elements, the loop won't be entered.

Another option would be to zip the array with the array where the first element has been dropped, allowing you to iterate through the pairs of elements with their successor elements:

for (nameA, nameB) in zip(names, names.dropFirst()) {
    print("\(nameA) loves \(nameB)")
}

This takes advantage of the fact that zip truncates the longer of the two sequences if they aren't of equal length. Therefore if the array has less than two elements, again, the loop won't be entered.

like image 182
Hamish Avatar answered Oct 11 '22 12:10

Hamish