Skip to content

Instantly share code, notes, and snippets.

@ShikiSuen
Last active October 23, 2023 20:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShikiSuen/1e4290848c5aedfe3af86d72187ec525 to your computer and use it in GitHub Desktop.
Save ShikiSuen/1e4290848c5aedfe3af86d72187ec525 to your computer and use it in GitHub Desktop.
Swift Index Revolver (requiring Swift 5.6)
// (c) 2021 and onwards Shiki Suen (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
import Foundation
extension Collection {
public func revolvedIndex(_ id: Int, clockwise: Bool = true, steps: Int = 1) -> Int {
if id < 0 || steps < 1 { return id }
var result = id
func revolvedIndexByOneStep(_ id: Int, clockwise: Bool = true) -> Int {
let newID = clockwise ? id + 1 : id - 1
if (0..<count).contains(newID) { return newID }
return clockwise ? 0 : count - 1
}
for _ in 0..<steps {
result = revolvedIndexByOneStep(result, clockwise: clockwise)
}
return result
}
}
extension Int {
public mutating func revolveAsIndex(with target: any Collection, clockwise: Bool = true, steps: Int = 1) {
if self < 0 || steps < 1 { return }
self = target.revolvedIndex(self, clockwise: clockwise, steps: steps)
}
}
// MARK: - Tests
let theArray: [Int] = [1,2,3,4]
var currentIndex = 0
for _ in 0..<8 {
currentIndex.revolveAsIndex(with: theArray)
print(currentIndex)
}
print("")
for _ in 0..<8 {
currentIndex.revolveAsIndex(with: theArray, clockwise: false)
print(currentIndex)
}
@ShikiSuen
Copy link
Author

ShikiSuen commented Jan 30, 2023

Swift 5.5:

// (c) 2021 and onwards Shiki Suen (MIT-NTL License).	
// ====================	
// This code is released under the MIT license (SPDX-License-Identifier: MIT)	

import Foundation

extension Collection {
  public func revolvedIndex(_ id: Int, clockwise: Bool = true, steps: Int = 1) -> Int {
    if id < 0 || steps < 1 { return id }
    var result = id
    func revolvedIndexByOneStep(_ id: Int, clockwise: Bool = true) -> Int {
      let newID = clockwise ? id + 1 : id - 1
      if (0..<count).contains(newID) { return newID }
      return clockwise ? 0 : count - 1
    }
    for _ in 0..<steps {
      result = revolvedIndexByOneStep(result, clockwise: clockwise)
    }
    return result
  }
}

extension Int {
  public mutating func revolveAsIndex<T: Collection>(with target: T, clockwise: Bool = true, steps: Int = 1) {
    if self < 0 || steps < 1 { return }
    self = target.revolvedIndex(self, clockwise: clockwise, steps: steps)
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment