# 按索引移动数组中的元素

`var array = [1, 2, 3, 4, 5]`

` ` mutating func shiftRight() { append(removeFirst()) }` `

1. 将数组拆分成由索引提供的两个
2. 将第一个数组附加到第二个数组的末尾

` `extension Array { mutating func shift(var amount: Int) { guard -count...count ~= amount else { return } if amount < 0 { amount += count } self = Array(self[amount ..< count] + self[0 ..< amount]) } }` `

` `extension Array { func shiftRight(var amount: Int = 1) -> [Element] { assert(-count...count ~= amount, "Shift amount out of bounds") if amount < 0 { amount += count } // this needs to be >= 0 return Array(self[amount ..< count] + self[0 ..< amount]) } mutating func shiftRightInPlace(amount: Int = 1) { self = shiftRight(amount) } } Array(1...10).shiftRight() // [2, 3, 4, 5, 6, 7, 8, 9, 10, 1] Array(1...10).shiftRight(7) // [8, 9, 10, 1, 2, 3, 4, 5, 6, 7]` `

` `extension Array { func shift(withDistance distance: Int = 1) -> Array<Element> { let offsetIndex = distance >= 0 ? self.index(startIndex, offsetBy: distance, limitedBy: endIndex) : self.index(endIndex, offsetBy: distance, limitedBy: startIndex) guard let index = offsetIndex else { return self } return Array(self[index ..< endIndex] + self[startIndex ..< index]) } mutating func shiftInPlace(withDistance distance: Int = 1) { self = shift(withDistance: distance) } }` `

` `let array1 = Array(1...10) let newArray = array1.shift(withDistance: 3) print(newArray) // prints: [4, 5, 6, 7, 8, 9, 10, 1, 2, 3] var array2 = Array(1...10) array2.shiftInPlace(withDistance: -2) print(array2) // prints: [9, 10, 1, 2, 3, 4, 5, 6, 7, 8] let array3 = Array(1...10) let newArray3 = array3.shift(withDistance: 30) print(newArray3) // prints: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] let array4 = Array(1...10) let newArray4 = array4.shift(withDistance: 0) print(newArray4) // prints: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] var array5 = Array(1...10) array5.shiftInPlace() print(array5) // prints: [2, 3, 4, 5, 6, 7, 8, 9, 10, 1]` `

• 转移数量大于`count`会导致环绕。
• 以负数移动翻转方向
• 以位移二进制运算符（ `<<``<<=``>>``>>=` ）显示`>>=`

` `extension Array { func shiftedLeft(by rawOffset: Int = 1) -> Array { let clampedAmount = rawOffset % count let offset = clampedAmount < 0 ? count + clampedAmount : clampedAmount return Array(self[offset ..< count] + self[0 ..< offset]) } func shiftedRight(by rawOffset: Int = 1) -> Array { return self.shiftedLeft(by: -rawOffset) } mutating func shiftLeft(by rawOffset: Int = 1) { self = self.shiftedLeft(by: rawOffset) } mutating func shiftRight(by rawOffset: Int = 1) { self = self.shiftedRight(by: rawOffset) } } //Swift 3 func << <T>(array: [T], offset: Int) -> [T] { return array.shiftedLeft(by: offset) } func >> <T>(array: [T], offset: Int) -> [T] { return array.shiftedRight(by: offset) } func <<= <T>(array: inout [T], offset: Int) { return array.shiftLeft(by: offset) } func >>= <T>(array: inout [T], offset: Int) { return array.shiftRight(by: offset) } /*// Swift 2.2 func << <T>(array: [T], offset: Int) -> [T] { return array.shiftedLeft(by: offset) } func >> <T>(array: [T], offset: Int) -> [T] { return array.shiftedRight(by: offset) } func <<= <T>(inout array: [T], offset: Int) { return array.shiftLeft(by: offset) } func >>= <T>(inout array: [T], offset: Int) { return array.shiftRight(by: offset) }*/` `

` `extension RandomAccessCollection where Self: RangeReplaceableCollection, Self.Index == Int, Self.IndexDistance == Int { func shiftedLeft(by rawOffset: Int = 1) -> RangeReplaceableSlice<Self> { let clampedAmount = rawOffset % count let offset = clampedAmount < 0 ? count + clampedAmount : clampedAmount return self[offset ..< count] + self[0 ..< offset] } func shiftedRight(by rawOffset: Int = 1) -> RangeReplaceableSlice<Self> { return self.shiftedLeft(by: -rawOffset) } mutating func shiftLeft(by rawOffset: Int = 1) { self = Self.init(self.shiftedLeft(by: rawOffset)) } mutating func shiftRight(by rawOffset: Int = 1) { self = Self.init(self.shiftedRight(by: rawOffset)) } //Swift 3 static func << (c: Self, offset: Int) -> RangeReplaceableSlice<Self> { return c.shiftedLeft(by: offset) } static func >> (c: Self, offset: Int) -> RangeReplaceableSlice<Self> { return c.shiftedRight(by: offset) } static func <<= (c: inout Self, offset: Int) { return c.shiftLeft(by: offset) } static func >>= (c: inout Self, offset: Int) { return c.shiftRight(by: offset) } }` `

` `//MARK: - Array extension Array { func shiftRight( amount: Int = 1) -> [Element] { var amountMutable = amount assert(-count...count ~= amountMutable, "Shift amount out of bounds") if amountMutable < 0 { amountMutable += count } // this needs to be >= 0 return Array(self[amountMutable ..< count] + self[0 ..< amountMutable]) } func reverseShift( amount: Int = 1) -> [Element] { var amountMutable = amount amountMutable = count-amountMutable-1 let a: [Element] = self.reverse() return a.shiftRight(amountMutable) } mutating func shiftRightInPlace(amount: Int = 1) { self = shiftRight(amount) } mutating func reverseShiftInPlace(amount: Int = 1) { self = reverseShift(amount) } }` `

` `Array(1...10).shiftRight() // [2, 3, 4, 5, 6, 7, 8, 9, 10, 1] Array(1...10).shiftRight(7) // [8, 9, 10, 1, 2, 3, 4, 5, 6, 7] Array(1...10).reverseShift() // [2, 1, 10, 9, 8, 7, 6, 5, 4, 3] Array(1...10).reverseShift(7) // [8, 7, 6, 5, 4, 3, 2, 1, 10, 9]` `

` `extension Array { mutating func rotateLeft(by rotations:Int) { let _ = // silence warnings (1..<Swift.max(1,count*((rotations+1)%(count+1)%1))) // will do zero or count - 1 swaps .reduce((i:0,r:count+rotations%count)) // i: swap index r:effective offset { s,_ in let j = (s.i+sr)%count // j: index of value for position i swap(&self[j],&self[si]) // swap to place value at rotated index return (j,sr) // continue with next index to place } } }` `

` `- (NSMutableArray *)shiftedArrayWithOffset:(NSInteger)offset { NSMutableArray *bufferArray = [[NSMutableArray alloc] initWithArray:originalArray]; for (int i = 0; i < offset; i++) { id object = [bufferArray firstObject]; [bufferArray removeObjectAtIndex:0]; [bufferArray addObject:object]; } return bufferArray; }` `

input：

` `var arr = [1,2,3,4,5] let k = 1 (num steps to rotate) let n = arr.count ( a little but faster )` `

` ` var temp = arr for i in 0..<n { arr[(n-i+k)%n] = temp[i] } result: [2, 1, 4, 3, 5]` `

` ` var temp = arr for i in 0..<n { arr[(i+k)%n] = temp[i] } result: [4, 1, 2, 3, 5]` `