Aaron
Aaron

Reputation: 6714

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)

Upvotes: 5

Views: 5444

Answers (3)

Will
Will

Reputation: 5490

Cleanest I can do for only positive integers is this

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

Upvotes: 0

Gamma
Gamma

Reputation: 1367

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

Upvotes: 1

user887210
user887210

Reputation:

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.

Upvotes: 8

Related Questions