如何从Swift中的数组中删除元素

Leo*_*Joy 207 arrays swift

如何在Apple的新语言Swift中取消/删除数组中的元素?

这是一些代码:

let animals = ["cats", "dogs", "chimps", "moose"]
Run Code Online (Sandbox Code Playgroud)

如何animals[2]从阵列中删除元素?

myt*_*thz 270

let关键字用于声明无法更改的常量.如果你想修改一个你应该使用的变量var,例如:

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

animals.remove(at: 2)  //["cats", "dogs", "moose"]
Run Code Online (Sandbox Code Playgroud)

保持原始集合不变的非变异替代方法是filter用于创建没有要删除的元素的新集合,例如:

let pets = animals.filter { $0 != "chimps" }
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考:`remove`返回被删除的元素:`let animal = animals.remove(at:2)` (3认同)
  • 我们可以只根据索引过滤吗?? (2认同)

Sur*_*gch 171

特定

var animals = ["cats", "dogs", "chimps", "moose"]
Run Code Online (Sandbox Code Playgroud)

删除第一个元素

animals.removeFirst() // "cats"
print(animals)        // ["dogs", "chimps", "moose"]
Run Code Online (Sandbox Code Playgroud)

删除最后一个元素

animals.removeLast() // "moose"
print(animals)       // ["cats", "dogs", "chimps"]
Run Code Online (Sandbox Code Playgroud)

删除索引处的元素

animals.remove(at: 2) // "chimps"
print(animals)           // ["cats", "dogs", "moose"]
Run Code Online (Sandbox Code Playgroud)

删除未知索引的元素

仅限一个元素

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

对于多个元素

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

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

或者

animals.index(of: "chimps").map { animals.remove(at: $0) }
Run Code Online (Sandbox Code Playgroud)

笔记

  • 上面的方法修改了数组(除了filter)并返回被删除的元素.
  • Swift指南映射过滤器减少
  • 如果您不想修改原始数组,可以使用dropFirstdropLast创建新数组.

更新为Swift 3


Dan*_*iel 157

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

通常您知道要在数组中删除的对象的引用.(您遍历数组并找到它,例如)在这种情况下,直接使用对象引用可能更容易,而不必传递其索引的任何位置.因此,我建议这个解决方案.它使用identity运算符 !==,您可以使用它来测试两个对象引用是否都引用同一个对象实例.

func delete(element: String) {
    list = list.filter() { $0 !== element }
}
Run Code Online (Sandbox Code Playgroud)

当然,这不仅适用于Strings.

  • 应该是`list = list.filter({$ 0!= element})` (21认同)
  • 如果您想与身份运营商核实,请勿使用. (5认同)
  • `array.indexOf({$ 0 == obj})` (3认同)
  • 请注意,如果其他对象引用`list`,则此删除将不会更新其他数组引用,因为您要将新数组分配给`list`.如果您使用此方法从数组中删除,这只是一个微妙的含义. (2认同)
  • 函数式编程范式依赖于不可变对象。即,你不改变它们。相反,您创建一个新对象。这就是删除、映射、减少等的作用。list 将是一个新创建的对象。在上面的代码片段中,我分配回列表一个新创建的对象。这对我有用,因为我按照函数式编程的方式设计代码。 (2认同)

Ska*_*aal 32

Swift 4: 这是一个很酷的简单扩展,可以删除数组中的元素,而无需过滤:

   extension Array where Element: Equatable {

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

}
Run Code Online (Sandbox Code Playgroud)

用法:

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

myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]
Run Code Online (Sandbox Code Playgroud)

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

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

myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
Run Code Online (Sandbox Code Playgroud)


小智 22

对于Swift4:

list = list.filter{$0 != "your Value"}
Run Code Online (Sandbox Code Playgroud)


Sol*_*oft 14

很少的操作涉及Swift中的Array

创建数组

var stringArray = ["One", "Two", "Three", "Four"]
Run Code Online (Sandbox Code Playgroud)

在数组中添加对象

stringArray = stringArray + ["Five"]
Run Code Online (Sandbox Code Playgroud)

从Index对象获取值

let x = stringArray[1]
Run Code Online (Sandbox Code Playgroud)

追加对象

stringArray.append("At last position")
Run Code Online (Sandbox Code Playgroud)

在索引处插入对象

stringArray.insert("Going", atIndex: 1)
Run Code Online (Sandbox Code Playgroud)

删除对象

stringArray.removeAtIndex(3)
Run Code Online (Sandbox Code Playgroud)

Concat对象值

var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
Run Code Online (Sandbox Code Playgroud)


Gui*_*uce 14

你可以这样做.首先确保Dog数组中确实存在,然后将其删除.for如果您认为Dog阵列上可能出现多次,请添加该语句.

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

for object in animals
{
    if object == animalToRemove{
        animals.removeAtIndex(animals.indexOf(animalToRemove)!)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您确定Dog退出阵列并且只发生一次就这样做:

animals.removeAtIndex(animals.indexOf(animalToRemove)!)
Run Code Online (Sandbox Code Playgroud)

如果你有两个,字符串和数字

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.removeAtIndex(array.indexOf(numberToRemove)!)
        }
    }
    if object is String
    {
        // this will deal with strings
        if object == animalToRemove
        {
        array.removeAtIndex(array.indexOf(animalToRemove)!)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Abo*_*tef 14

如果您有自定义对象数组,则可以按特定属性进行搜索,如下所示:

if let index = doctorsInArea.firstIndex(where: {$0.id == doctor.id}){
    doctorsInArea.remove(at: index)
}
Run Code Online (Sandbox Code Playgroud)

或者如果您想按名称搜索例如

if let index = doctorsInArea.firstIndex(where: {$0.name == doctor.name}){
    doctorsInArea.remove(at: index)
}
Run Code Online (Sandbox Code Playgroud)


dav*_*ynn 12

从Xcode 10+开始,根据WWDC 2018会议223,"拥抱算法",一个很好的方法将是mutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

Apple的例子:

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."
Run Code Online (Sandbox Code Playgroud)

请参阅Apple的文档

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

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

这种方法可能是首选,因为它可以很好地扩展(线性与二次),可读且干净.请记住,它只能在Xcode 10+中使用,而在撰写时,它是在Beta中.


小智 10

如果您不知道要删除的元素的索引,并且该元素符合Equatable协议,则可以执行以下操作:

animals.removeAtIndex(animals.indexOf("dogs")!)

请参阅Equatable协议答案:如何执行indexOfObject或正确的containsObject


Kru*_*nal 8

使用索引数组删除元素:

  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"]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 整数和索引的数组

    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]
    
    Run Code Online (Sandbox Code Playgroud)



使用另一个数组的元素值删除元素

  1. 整数数组

    let arrayResult = numbers.filter { element in
        return !indexesToRemove.contains(element)
    }
    print(arrayResult)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 字符串数组

    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"]
    
    Run Code Online (Sandbox Code Playgroud)

  • 这是一个线性答案,它对于更好的编码和快速执行非常有效. (3认同)

nbu*_*urk 7

我想出了以下扩展,它负责从 an 中删除元素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)
  }
  
}
  
Run Code Online (Sandbox Code Playgroud)

用法:

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

var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
Run Code Online (Sandbox Code Playgroud)


Jer*_*ome 7

斯威夫特 5

guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)
Run Code Online (Sandbox Code Playgroud)


Obj*_*eTC 6

关于@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)
}
Run Code Online (Sandbox Code Playgroud)

可以预见的是,你可以通过在repeat/while循环中嵌入上面的if语句来删除"所有"红色汽车,并附加一个else块来设置一个标志以"断开"循环.