Considérons le tableau [1,2,3,4]
. Comment puis-je réorganiser l'élément de tableau à la nouvelle position.
Par exemple:
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]
.
let element = arr.remove(at: 3)
arr.insert(element, at: 2)
et sous forme de fonction:
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
}
Cela met 3 en position 4.
let element = arr.removeAtIndex(3)
arr.insert(element, atIndex: 2)
Vous pouvez même créer une fonction générale:
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
}
La var
arr
est nécessaire ici, car vous ne pouvez pas muter le paramètre d'entrée sans le spécifier comme étant in-out
. Dans notre cas, cependant, nous obtenons des fonctions pures sans effets secondaires, ce qui est beaucoup plus facile à raisonner, à mon avis. Vous pourriez alors l'appeler comme ceci:
let arr = [1,2,3,4]
rearrange(arr, fromIndex: 2, toIndex: 0) //[3,1,2,4]
modifier/mettre à jour: 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)
}
}
var numbers = [1,2,3,4]
numbers.rearrange(from: 1, to: 2)
print(numbers) // [1, 3, 2, 4]
Toutes les bonnes réponses! Voici une solution Swift 4 plus complète, axée sur la performance et les bonus pour les fans de benchmark et 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)
}
}
Bon conseil de Leo.
pour 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)
var arr = ["one", "two", "three", "four", "five"]
// Swap elements at index: 2 and 3
print(arr)
arr.swapAt(2, 3)
print(arr)
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)
}
}
Nous pouvons utiliser la méthode swap pour échanger des éléments dans un tableau:
var arr = ["one", "two", "three", "four", "five"]
// Swap elements at index: 2 and 3
print(arr)
swap(&arr[2], &arr[3])
print(arr)
Solution efficace:
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
}
}
Swift 4 - Solution permettant de déplacer un groupe d'éléments d'un IndexSet
index, de les regrouper et de les déplacer vers un index de destination. Réalisé via une extension à RangeReplaceableCollection
. Inclut une méthode pour supprimer et retourner tous les éléments dans un IndexSet
. Je ne savais pas comment contraindre l'extension à une forme plus générale que celle de l'élément tout en conservant la possibilité de construire IndexSets
car ma connaissance de Swift Protocoles est pas si vaste.
extension RangeReplaceableCollection where Self.Indices.Element == Int {
/**
Removes the items contained in an `IndexSet` from the collection.
Items outside of the collection range will be ignored.
- Parameter indexSet: The set of indices to be removed.
- Returns: Returns the removed items as an `Array<Self.Element>`.
*/
@discardableResult
mutating func removeItems(in indexSet: IndexSet) -> [Self.Element] {
var returnItems = [Self.Element]()
for (index, _) in self.enumerated().reversed() {
if indexSet.contains(index) {
returnItems.insert(self.remove(at: index), at: startIndex)
}
}
return returnItems
}
/**
Moves a set of items with indices contained in an `IndexSet` to a
destination index within the collection.
- Parameters:
- indexSet: The `IndexSet` of items to move.
- destinationIndex: The destination index to which to move the items.
- Returns: `true` if the operation completes successfully else `false`.
If any items fall outside of the range of the collection this function
will fail with a fatal error.
*/
@discardableResult
mutating func moveItems(from indexSet: IndexSet, to destinationIndex: Index) -> Bool {
guard indexSet.isSubset(of: IndexSet(indices)) else {
debugPrint("Source indices out of range.")
return false
}
guard (0..<self.count + indexSet.count).contains(destinationIndex) else {
debugPrint("Destination index out of range.")
return false
}
let itemsToMove = self.removeItems(in: indexSet)
let modifiedDestinationIndex:Int = {
return destinationIndex - indexSet.filter { destinationIndex > $0 }.count
}()
self.insert(contentsOf: itemsToMove, at: modifiedDestinationIndex)
return true
}
}
Il n'y a pas de fonctionnalité de déplacement dans Swift pour les tableaux. Vous pouvez prendre un objet à un index en le supprimant et le placer dans votre index favori à l'aide de 'insert'
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
Mise à jour avec Swift 4, index de tableau de balayage
for (index,addres) in self.address.enumerated() {
if addres.defaultShipping == true{
let defaultShipping = self.address.remove(at: index)
self.address.insert(defaultShipping, at: 0)
}
}