'Cleanest way to wrap array index?

Say I have an array of 5 Ints. What would be the most efficient way to wrap the index of the array if the index were incremented or decremented (for example) the following occurs?

where n = 0: arr[n-1] // -> arr[4] (wraps from 0 back to the end of the array)

where n = 2: arr[n+1] // -> arr[3] (behaves as normal)

where n = 4: arr[n+1] // -> arr[0] (wraps to 0 from the end of the array)



Solution 1:[1]

You can use the mod operation which will get you to a range of -count to count, then add count back in and mod again:

let foo = [0, 1, 2, 3, 4, 5]

for i in -6...7 {
  print(i, foo[(i % foo.count + foo.count) % foo.count])
}

//  -6 0
//  -5 1
//  -4 2
//  -3 3
//  -2 4
//  -1 5
//  0 0
//  1 1
//  2 2
//  3 3
//  4 4
//  5 5
//  6 0

This works for both directions.

Solution 2:[2]

A bit late to the party, but if you're facing the same issue and have a lot of use cases for wrap-around array indices, you could also put the %-solution from the accepted answer in a simple subscript extension of Array, like so:

extension Array {
    subscript (wrapping index: Int) -> Element {
        return self[(index % self.count + self.count) % self.count]
    }
}

Example Usage:

let array = ["a","b","c"]
print( array[wrapping: 0] )   // a
print( array[wrapping: 4] )   // b
print( array[wrapping: -1] )  // c

Solution 3:[3]

Cleanest I can do for only positive integers is this

extension Array{
    subscript(wrapAround index: Int) -> Element {
        return self[index % self.count]
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Gamma
Solution 3 Will