Reputation: 6714
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
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
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
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