如何在Swift中将数组项重新排列到新位置?

Mor*_*hoi 52 arrays swift

考虑数组[1,2,3,4].如何将数组项重新排列到新位置.

例如:

put 3 into position 4 [1,2,4,3]

put 4 in to position 1 [4,1,2,3]

put 2 into position 3 [1,3,2,4].

Luk*_*itz 97

Swift 3.0+:

let element = arr.remove(at: 3)
arr.insert(element, at: 2)
Run Code Online (Sandbox Code Playgroud)

并以功能形式:

func rearrange<T>(array: Array<T>, fromIndex: Int, toIndex: Int) -> Array<T>{
    var arr = array
    let element = arr.remove(at: fromIndex)
    arr.insert(element, at: toIndex)

    return arr
}
Run Code Online (Sandbox Code Playgroud)

Swift 2.0:

这使得3成为第4位.

let element = arr.removeAtIndex(3)
arr.insert(element, atIndex: 2)
Run Code Online (Sandbox Code Playgroud)

你甚至可以做一般功能:

func rearrange<T>(array: Array<T>, fromIndex: Int, toIndex: Int) -> Array<T>{
    var arr = array
    let element = arr.removeAtIndex(fromIndex)
    arr.insert(element, atIndex: toIndex)

    return arr
}
Run Code Online (Sandbox Code Playgroud)

var arr这里需要的,因为你不能没有指明它是变异的输入参数in-out.然而,在我们的例子中,我们得到了一个没有副作用的纯函数,在我看来,这更容易推理.然后你可以像这样调用它:

let arr = [1,2,3,4]
rearrange(arr, fromIndex: 2, toIndex: 0) //[3,1,2,4]
Run Code Online (Sandbox Code Playgroud)

  • 对于toIndex大于fromIndex的情况,这里的解决方案是否有缺陷,因为removeAtIndex会更改目标toIndex点的Index? (4认同)

Leo*_*bus 38

编辑/更新:Swift 3.x

extension RangeReplaceableCollection where Indices: Equatable {
    mutating func rearrange(from: Index, to: Index) {
        precondition(from != to && indices.contains(from) && indices.contains(to), "invalid indices")
        insert(remove(at: from), at: to)
    }
}
Run Code Online (Sandbox Code Playgroud)
var numbers = [1,2,3,4]
numbers.rearrange(from: 1, to: 2)

print(numbers)  // [1, 3, 2, 4]
Run Code Online (Sandbox Code Playgroud)

  • Leo,在我看来,“删除”操作会有一个副作用,它会影响该功能的工作方式,具体取决于您是向前还是向后移动项目。然而,看来我在这一点上是错误的。 (2认同)

Ian*_*hek 24

所有好的答案!这是一个更完整的Swift 4解决方案,其中包括性能和基准和GIF粉丝的奖金.✌️

extension Array where Element: Equatable
{
    mutating func move(_ element: Element, to newIndex: Index) {
        if let oldIndex: Int = self.index(of: element) { self.move(from: oldIndex, to: newIndex) }
    }
}

extension Array
{
    mutating func move(from oldIndex: Index, to newIndex: Index) {
        // Don't work for free and use swap when indices are next to each other - this
        // won't rebuild array and will be super efficient.
        if oldIndex == newIndex { return }
        if abs(newIndex - oldIndex) == 1 { return self.swapAt(oldIndex, newIndex) }
        self.insert(self.remove(at: oldIndex), at: newIndex)
    }
}
Run Code Online (Sandbox Code Playgroud)

GIF

  • 考虑“[A,B,C,D]”。将索引“3”处的项目移动到“0”会得到“[D,A,B,C]”。将索引“3”处的项目交换为“0”会得到“[D,B,C,A]”。 (2认同)

ing*_*nti 19

来自狮子座的精彩小贴士.

对于Swift 3:

extension Array {  
    mutating func rearrange(from: Int, to: Int) {
        insert(remove(at: from), at: to)
    }
}

var myArray = [1,2,3,4]
myArray.rearrange(from: 1, to: 2)   
print(myArray)
Run Code Online (Sandbox Code Playgroud)


Vin*_*dan 11

var arr = ["one", "two", "three", "four", "five"]

// Swap elements at index: 2 and 3
print(arr)
arr.swapAt(2, 3)
print(arr)
Run Code Online (Sandbox Code Playgroud)


Zel*_*lko 7

斯威夫特4.2

extension Array where Element: Equatable {
    mutating func move(_ item: Element, to newIndex: Index) {
        if let index = index(of: item) {
            move(at: index, to: newIndex)
        }
    }

    mutating func bringToFront(item: Element) {
        move(item, to: 0)
    }

    mutating func sendToBack(item: Element) {
        move(item, to: endIndex-1)
    }
}

extension Array {
    mutating func move(at index: Index, to newIndex: Index) {
        insert(remove(at: index), at: newIndex)
    }
}
Run Code Online (Sandbox Code Playgroud)


Muh*_*Ali 5

我们可以使用swap方法交换数组中的项:

var arr = ["one", "two", "three", "four", "five"]

// Swap elements at index: 2 and 3
print(arr)
swap(&arr[2], &arr[3])
print(arr)
Run Code Online (Sandbox Code Playgroud)