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

时间:2016-04-11 06:54:34

标签: 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]

16 个答案:

答案 0 :(得分:90)

Swift 3.0 +:

let element = arr.remove(at: 3)
arr.insert(element, at: 2)

并以函数形式:

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
}

Swift 2.0:

这将3放入第4位。

let element = arr.removeAtIndex(3)
arr.insert(element, atIndex: 2)

你甚至可以做一般功能:

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
}

此处需要var arr,因为如果不将输入参数指定为in-out,则无法改变输入参数。然而,在我们的例子中,我们得到了一个没有副作用的纯函数,在我看来,这更容易推理。 然后你可以这样称呼它:

let arr = [1,2,3,4]
rearrange(arr, fromIndex: 2, toIndex: 0) //[3,1,2,4]

答案 1 :(得分:20)

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

sed -n '/^get\.idea/s/^.*(\(.*\)).*/\1/ p' idea.js | 
awk -F, 'BEGIN {print "idea, description";OFS=","} (NR % 2 ) == 1
         {save=$2} (NR % 2) == 0 {print save, $2}' > idea.csv

GIF

答案 2 :(得分:17)

来自狮子座的好消息。

对于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)

答案 3 :(得分:7)

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

// Swap elements at index: 2 and 3
print(arr)
arr.swapAt(2, 3)
print(arr)

答案 4 :(得分: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)

答案 5 :(得分:3)

Swift 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)
    }
}

答案 6 :(得分:1)

对于数组,swift中没有移动功能。您可以通过从索引中删除对象并使用“插入”

将其放在您喜欢的索引中
var swiftarray = [1,2,3,4]
let myobject = swiftarray.removeAtIndex(1) // 2 is the object at 1st index
let myindex = 3
swiftarray.insert(myobject, atIndex: myindex) // if you want to insert the    object to a particular index here it is 3
swiftarray.append(myobject) // if you want to move the object to last index

答案 7 :(得分:1)

快速4 -解决方案,用于从IndexSet索引中移动一组项目,将它们分组并移动到目标索引。通过扩展RangeReplaceableCollection实现。包括用于删除并返回IndexSet中所有项目的方法。由于我对Swift协议的了解并不广泛,因此我不确定如何将扩展约束为比整数约束更广泛的形式,而不是将元素约束为整数。

IndexSets

答案 8 :(得分:1)

有效的解决方案:

extension Array 
{
    mutating func move(from sourceIndex: Int, to destinationIndex: Int)
    {
        guard
            sourceIndex != destinationIndex
            && Swift.min(sourceIndex, destinationIndex) >= 0
            && Swift.max(sourceIndex, destinationIndex) < count
        else {
            return
        }

        let direction = sourceIndex < destinationIndex ? 1 : -1
        var sourceIndex = sourceIndex

        repeat {
            let nextSourceIndex = sourceIndex + direction
            swapAt(sourceIndex, nextSourceIndex)
            sourceIndex = nextSourceIndex
        }
        while sourceIndex != destinationIndex
    }
}

答案 9 :(得分:0)

  

使用Swift 4进行更新,   滑动数组索引

for (index,addres) in self.address.enumerated() {
     if addres.defaultShipping == true{
          let defaultShipping = self.address.remove(at: index)
          self.address.insert(defaultShipping, at: 0)
     }
}

答案 10 :(得分:0)

@ian提供了很好的解决方案,但是当数组超出限制时也会崩溃

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

    public mutating func moveToFirst(item: Element) {
        self.move(item, to: 0)
    }

    public mutating func move(from oldIndex: Index, to newIndex: Index) {
        // won't rebuild array and will be super efficient.
        if oldIndex == newIndex { return }
        // Index out of bound handle here
        if newIndex >= self.count { return }
        // Don't work for free and use swap when indices are next to each other - this
        if abs(newIndex - oldIndex) == 1 { return self.swapAt(oldIndex, newIndex) }
        // Remove at old index and insert at new location
        self.insert(self.remove(at: oldIndex), at: newIndex)
    }
}

答案 11 :(得分:0)

功能(不是快速的,而是通用的。查找/删除/插入):

func c_move_to(var array:Array,var from:Int,var to:Int):

    var val = array[from]
    array.remove(from)
    array.insert(to,val)
    return array

使用方法:

print("MOVE 0 to 3  [1,2,3,4,5]"  , c_move_to([1,2,3,4,5],0,3))
print("MOVE 1 to 2  [1,2,3,4,5]"  , c_move_to([1,2,3,4,5],1,2)) 

吐出来:

MOVE 0 to 3  [1,2,3,4,5][2, 3, 4, 1, 5]
MOVE 1 to 2  [1,2,3,4,5][1, 3, 2, 4, 5]

答案 12 :(得分:0)

func adjustIndex(_ index: Int, forRemovalAt removed: Int) -> Int {
    return index <= removed ? index : index - 1
}

extension Array
{
    mutating func move(from oldIndex: Index, to newIndex: Index) {
        insert(remove(at: oldIndex), at: adjustIndex(newIndex, forRemovalAt: oldIndex))
    }
}

答案 13 :(得分:0)

这是一个解决方案,其中包含就地更改数组和返回更改后的数组的函数:

extension Array {
    func rearranged(from fromIndex: Int, to toIndex: Int) -> [Element] {
        var arr = self
        let element = arr.remove(at: fromIndex)
        
        if toIndex >= self.count {
            arr.append(element)
        } else {
            arr.insert(element, at: toIndex)
        }
        return arr
    }
    
    mutating func rearrange(from fromIndex: Int, to toIndex: Int) {
        let element = self.remove(at: fromIndex)
        if toIndex >= self.count {
            self.append(element)
        } else {
            self.insert(element, at: toIndex)
        }
    }
}

答案 14 :(得分:-1)

Leo Dabus的解决方案非常好但是使用前提条件(从!=到&amp;&amp; indices.contains(从!=到&amp;&amp; indices.contains(to),&#34;无效索引&# 34;),如果条件不满足将使应用程序崩溃。我将其更改为警告和if语句 - 如果由于某种原因未满足条件,则没有任何反应并且应用程序继续。我认为我们应该避免扩展可能会崩溃应用程序。如果你希望你可以让重新排列函数返回一个Bool - 如果成功则为true,如果失败则为false。 更安全的解决方案:

extension Array {
mutating func rearrange(from: Int, to: Int) {
    guard from != to else { return }
    //precondition(from != to && indices.contains(from) && indices.contains(to), "invalid indexes")
    if indices.contains(from) && indices.contains(to) {
        insert(remove(at: from), at: to)
    }
}

答案 15 :(得分:-1)

该解决方案如何? 要更改的元素和要更改的元素都已更改。

// Extenstion

extension Array where Element: Equatable {
  mutating func change(_ element: Element, to newIndex: Index) {
    if let firstIndex = self.firstIndex(of: element) {
      self.insert(element, at: 0)
      self.remove(at: firstIndex + 1)
    }
  }
}

// Example

var testArray = ["a", "b", "c", "EE", "d"]
testArray.change("EE", to: 0)

// --> Result
// ["EE", "a", "b", "c", "d"]