如何从Swift数组中删除一个元素

如何在苹果的新语言Swift中取消设置/删除数组中的元素?

下面是一些代码:

let animals = ["cats", "dogs", "chimps", "moose"]

如何从数组中移除元素animals[2] ?

434756 次浏览

let关键字用于声明不可更改的常量。如果你想修改一个变量,你应该使用var来代替,例如:

var animals = ["cats", "dogs", "chimps", "moose"]


animals.remove(at: 2)  //["cats", "dogs", "moose"]

一个保持原始集合不变的非突变替代方法是使用filter创建一个新的集合,不删除你想要删除的元素,例如:

let pets = animals.filter { $0 != "chimps" }

这应该做到(未测试):

animals[2...3] = []

编辑:你需要使它成为var,而不是let,否则它是一个不可变的常量。

Swift中很少涉及数组操作

创建数组

var stringArray = ["One", "Two", "Three", "Four"]

在数组中添加对象

stringArray = stringArray + ["Five"]

从索引对象中获取值

let x = stringArray[1]

添加对象

stringArray.append("At last position")

在索引处插入对象

stringArray.insert("Going", at: 1)

删除对象

stringArray.remove(at: 3)

Concat对象值

var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"

上面的答案似乎假定您知道要删除的元素的索引。

通常你知道数组中你想要删除的对象的参考。在这种情况下,直接使用对象引用可能会更容易,而不必到处传递它的索引。因此,我建议这个解决方案。它使用标识符 !==,用于测试两个对象引用是否都引用同一个对象实例。

func delete(element: String) {
list = list.filter { $0 != element }
}

当然,这不仅适用于__abc。

如果你不知道你想要删除的元素的索引,并且元素符合Equatable协议,你可以这样做:

animals.remove(at: animals.firstIndex(of: "dogs")!)

参见Equatable协议答案:我如何做indexOfObject或适当的containsObject

你可以这么做。首先确保Dog确实存在于数组中,然后删除它。如果你认为Dog可能在数组中发生多次,则添加for语句。

var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"


for object in animals {
if object == animalToRemove {
animals.remove(at: animals.firstIndex(of: animalToRemove)!)
}
}

如果你确定Dog在数组中退出并且只发生了一次,那么就这样做:

animals.remove(at: animals.firstIndex(of: animalToRemove)!)

如果两者都有,字符串和数字

var array = [12, 23, "Dog", 78, 23]
let numberToRemove = 23
let animalToRemove = "Dog"


for object in array {


if object is Int {
// this will deal with integer. You can change to Float, Bool, etc...
if object == numberToRemove {
array.remove(at: array.firstIndex(of: numberToRemove)!)
}
}
if object is String {
// this will deal with strings
if object == animalToRemove {
array.remove(at: array.firstIndex(of: animalToRemove)!)
}
}
}

我提出了以下扩展,它负责从Array中删除元素,假设Array中的元素实现了Equatable:

extension Array where Element: Equatable {
  

mutating func removeEqualItems(_ item: Element) {
self = self.filter { (currentItem: Element) -> Bool in
return currentItem != item
}
}


mutating func removeFirstEqualItem(_ item: Element) {
guard var currentItem = self.first else { return }
var index = 0
while currentItem != item {
index += 1
currentItem = self[index]
}
self.remove(at: index)
}
  

}
  

用法:

var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]


var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]

鉴于

var animals = ["cats", "dogs", "chimps", "moose"]

删除第一个元素

animals.removeFirst() // "cats"
print(animals)        // ["dogs", "chimps", "moose"]

删除最后一个元素

animals.removeLast() // "moose"
print(animals)       // ["cats", "dogs", "chimps"]

删除索引处的元素

animals.remove(at: 2) // "chimps"
print(animals)           // ["cats", "dogs", "moose"]

删除未知索引的元素

只针对一个元素

if let index = animals.firstIndex(of: "chimps") {
animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]

对于多个元素

var animals = ["cats", "dogs", "chimps", "moose", "chimps"]


animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]

笔记

  • 上述方法就地修改数组(filter除外)并返回被删除的元素。
  • Map Filter Reduce Swift Guide .
  • 如果你不想修改原始数组,你可以使用dropFirstdropLast来创建一个新数组。

更新至Swift 5.2

关于@Suragch的替代方案“删除未知索引的元素”:

“indexOf(element)”有一个更强大的版本,它将匹配谓词而不是对象本身。它使用相同的名称,但它被myObjects.indexOf{$0调用。property = valueToMatch}。它返回myObjects数组中找到的第一个匹配项的索引。

如果元素是一个对象/结构,您可能希望根据其属性之一的值删除该元素。例如,你有一个Car类拥有Car。color属性,你想从carsArray中删除“红色”汽车。

if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}

可以预见的是,您可以通过在repeat/while循环中嵌入上述if语句,并附加一个else块来设置一个“打破”循环的标志,从而重新工作以删除“所有”红色汽车。

如果你有一个自定义对象数组,你可以像这样通过特定的属性进行搜索:

if let index = doctorsInArea.firstIndex(where: {$0.id == doctor.id}){
doctorsInArea.remove(at: index)
}

或者如果你想通过名字来搜索

if let index = doctorsInArea.firstIndex(where: {$0.name == doctor.name}){
doctorsInArea.remove(at: index)
}

扩展删除字符串对象

extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}

< >强劲迅速5: 这是一个很酷很简单的扩展,可以在不过滤的情况下删除数组中的元素

   extension Array where Element: Equatable {


// Remove first collection element that is equal to the given `object`:
mutating func remove(object: Element) {
guard let index = firstIndex(of: object) else {return}
remove(at: index)
}


}

用法:

var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"


myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]

也适用于其他类型,例如Int,因为Element是一个泛型类型:

var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17


myArray.remove(object: objectToRemove) // [4, 8, 6, 2]

我使用这个扩展,几乎与Varun的一样,但这一个(下面)是万能的:

 extension Array where Element: Equatable  {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}

使用索引数组删除元素:

  1. 字符串和索引数组

    let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
    let indexAnimals = [0, 3, 4]
    let arrayRemainingAnimals = animals
    .enumerated()
    .filter { !indexAnimals.contains($0.offset) }
    .map { $0.element }
    
    
    print(arrayRemainingAnimals)
    
    
    //result - ["dogs", "chimps", "cow"]
    
  2. Array of Integers and indexes

    var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    let indexesToRemove = [3, 5, 8, 12]
    
    
    numbers = numbers
    .enumerated()
    .filter { !indexesToRemove.contains($0.offset) }
    .map { $0.element }
    
    
    print(numbers)
    
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    



Remove elements using element value of another array

  1. Arrays of integers

    let arrayResult = numbers.filter { element in
    return !indexesToRemove.contains(element)
    }
    print(arrayResult)
    
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    
  2. Arrays of strings

    let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
    let arrayRemoveLetters = ["a", "e", "g", "h"]
    let arrayRemainingLetters = arrayLetters.filter {
    !arrayRemoveLetters.contains($0)
    }
    
    
    print(arrayRemainingLetters)
    
    
    //result - ["b", "c", "d", "f", "i"]
    

Swift4:

list = list.filter{$0 != "your Value"}

在Xcode 10+中,根据2018年全球开发者大会第223场,“拥抱算法”,,一个好的方法将是mutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

苹果的例子:

var phrase = "The rain in Spain stays mainly in the plain."
let vowels: Set<Character> = ["a", "e", "i", "o", "u"]


phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."

看到苹果公司的文档

所以在OP的例子中,移除动物[2],“黑猩猩”:

var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }

这种方法可能是首选的,因为它的伸缩性很好(线性vs二次),可读和干净。请记住,它只能在Xcode 10+中工作,并且在写这篇文章时是测试版。

斯威夫特5

guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)
要从数组中删除元素,使用remove(at:)removeLast()removeAll().

yourArray = [1,2,3,4]

删除2位置的值

yourArray.remove(at: 2)

从数组中移除最后一个值

yourArray.removeLast()

从集合中移除所有成员

yourArray.removeAll()