Roman Busygin
Roman Busygin

Reputation: 543

Iterate over all elements in the array in order starting given index

Say, I have an array let array = [ "foo", "bar", "baz", "foobar", "qux" ] and an index 3 inside this array. I want to iterate all elements in the array in a following order foobar (element at index 3), qux (at index 4), foo (at index 0, etc.), bar, baz.

Not so elegant solution would look like this:

for index in givenIndex ..< array.endIndex {
  // do some work with array[index]
}

for index in array.startIndex ..< givenIndex {
  // do the same work with array[index]
}

Is there a more elegant solution?

Upvotes: 1

Views: 482

Answers (2)

vacawama
vacawama

Reputation: 154593

To keep from repeating your work block you could convert your ranges to arrays and add them:

let givenIndex = 3
let array = [ "foo", "bar", "baz", "foobar", "qux" ]

for index in Array(givenIndex ..< array.endIndex) + Array(0 ..< givenIndex) {
    // do some work with array[index]
    print(array[index])
}

Alternative Answer

Since elegant is in the eye of the beholder, another way to avoid repeating your work block is to put your ranges in an array and then select them in order before iterating over them:

for range in [givenIndex ..< array.endIndex, 0 ..< givenIndex] {
    for index in range {
        // do some work with array[index]
        print(array[index])
    }
}

Upvotes: 3

oisdk
oisdk

Reputation: 10091

An extension and the % operator should work:

extension CollectionType where Index : IntegerType, Index.Distance == Index {
  func offset(by: Index) -> [Generator.Element] {
    guard by >= 0 else { return offset(by+count) }
    return (by..<(by+count))
      .map { i in self[i % count + startIndex] }
  }
}


let array = [ "foo", "bar", "baz", "foobar", "qux" ]

array.offset( 1) // ["foobar", "qux", "foo", "bar", "baz"]
array.offset(-1) // ["qux", "foo", "bar", "baz", "foobar"]

let s = array.suffixFrom(2) // ["baz", "foobar", "qux"]

s.offset( 1) // ["foobar", "qux", "baz"]
s.offset(-1) // ["qux", "baz", "foobar"]

Upvotes: 3

Related Questions