如何交换 swift 数组中的元素?

How to exchange elements in swift array?

我有一个简单的数组,例如:

var cellOrder = [1,2,3,4]

我想交换元素,例如假设第二个元素与第一个元素。

结果将是:

[2,1,3,4]

我知道我们可以使用 exchangeObjectAtIndexNSMutableArray 但我想使用 swift 数组。有什么方法可以对 swift [Int] 数组做同样的事情?

使用swap:

var cellOrder = [1,2,3,4]
swap(&cellOrder[0], &cellOrder[1])

或者,您可以将其分配为元组:

(cellOrder[0], cellOrder[1]) = (cellOrder[1], cellOrder[0])

一个选项是:

cellOrder[0...1] = [cellOrder[1], cellOrder[0]]

Swift 4

swapAt(_:_:):

cellOrder.swapAt(index0, index1)

使用swapAt方法,

var arr = [10,20,30,40,50]
arr.swapAt(2, 3)

使用索引交换元素。

详情

  • Xcode 版本 10.3 (10G8), Swift 5

基本(不安全但快速)变体

unsafe - means that you can catch fatal error when you will try to make a swap using wrong (out of the range) index of the element in array

var array = [1,2,3,4]
// way 1
(array[0],array[1]) = (array[1],array[0])
// way 2
array.swapAt(2, 3)

print(array)

安全交换的解决方案

  • 保存交换尝试(检查索引)
  • 可能知道什么索引错了

do not use this solution when you have to swap a lot of elements in the loop. This solution validates both (i,j) indexes (add some extra logic) in the swap functions which will make your code slower than usage of standard arr.swapAt(i,j). It is perfect for single swaps or for small array. But, if you will decide to use standard arr.swapAt(i,j) you will have to check indexes manually or to be sure that indexes are not out of the range.

import Foundation

enum SwapError: Error {
    case wrongFirstIndex
    case wrongSecondIndex
}

extension Array {
    mutating func detailedSafeSwapAt(_ i: Int, _ j: Int) throws {
        if !(0..<count ~= i) { throw SwapError.wrongFirstIndex }
        if !(0..<count ~= j) { throw SwapError.wrongSecondIndex }
        swapAt(i, j)
    }

    @discardableResult mutating func safeSwapAt(_ i: Int, _ j: Int) -> Bool {
        do {
            try detailedSafeSwapAt(i, j)
            return true
        } catch {
            return false
        }
    }
}

安全交换的使用

result = arr.safeSwapAt(5, 2)

//or
if arr.safeSwapAt(5, 2) {
    //Success
} else {
    //Fail
}

//or
arr.safeSwapAt(4, 8)

//or
do {
    try arr.detailedSafeSwapAt(4, 8)
} catch let error as SwapError {
    switch error {
    case .wrongFirstIndex: print("Error 1")
    case .wrongSecondIndex: print("Error 2")
    }
}

安全交换的完整样本

var arr = [10,20,30,40,50]
print("Original array: \(arr)")

print("\nSample 1 (with returning Bool = true): ")
var result = arr.safeSwapAt(1, 2)
print("Result: " + (result ? "Success" : "Fail"))
print("Array: \(arr)")

print("\nSample 2 (with returning Bool = false):")
result = arr.safeSwapAt(5, 2)
print("Result: " + (result ? "Success" : "Fail"))
print("Array: \(arr)")

print("\nSample 3 (without returning value):")
arr.safeSwapAt(4, 8)
print("Array: \(arr)")

print("\nSample 4 (with catching error):")
do {
    try arr.detailedSafeSwapAt(4, 8)
} catch let error as SwapError {
    switch error {
    case .wrongFirstIndex: print("Error 1")
    case .wrongSecondIndex: print("Error 2")
    }
}
print("Array: \(arr)")


print("\nSample 5 (with catching error):")
do {
    try arr.detailedSafeSwapAt(7, 1)
} catch let error as SwapError {
    print(error)
}
print("Array: \(arr)")

安全交换的完整示例日志

Original array: [10, 20, 30, 40, 50]

Sample 1 (with returning Bool = true): 
Result: Success
Array: [10, 30, 20, 40, 50]

Sample 2 (with returning Bool = false):
Result: Fail
Array: [10, 30, 20, 40, 50]

Sample 3 (without returning value):
Array: [10, 30, 20, 40, 50]

Sample 4 (with catching error):
Error 2
Array: [10, 30, 20, 40, 50]

Sample 5 (with catching error):
wrongFirstIndex
Array: [10, 30, 20, 40, 50]