Answers:
该let
关键字是声明不能改变的常量。如果要修改变量,则应var
改用,例如:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.remove(at: 2) //["cats", "dogs", "moose"]
一个使原始集合保持不变的非变异替代方法是filter
用于创建一个新集合,而无需删除想要删除的元素,例如:
let pets = animals.filter { $0 != "chimps" }
给定
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
),并返回已删除的元素。dropFirst
或dropLast
创建一个新阵列。更新到Swift 5.2
上面的答案似乎假设您知道要删除的元素的索引。
通常,您知道要在数组中删除的对象的引用。(例如,您遍历了数组并找到了它),在这种情况下,直接使用对象引用而不需要传递其索引的位置可能会更容易。因此,我建议这种解决方案。它使用身份运算符 !==
,您可以使用该运算符来测试两个对象引用是否都引用同一对象实例。
func delete(element: String) {
list = list.filter() { $0 !== element }
}
当然,这不仅适用于String
s。
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
list
此删除操作,则不会更新其他数组引用,因为您正在将新数组分配给list
。如果您使用这种方法从数组中删除,则只是一个隐含的含义。
Swift 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]
对于Swift4:
list = list.filter{$0 != "your Value"}
从Xcode 10+开始,根据WWDC 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."
请参阅Apple文档
因此,在OP的示例中,删除了动物[2],“黑猩猩”:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
此方法可能是首选,因为它可以很好地缩放(线性vs二次方),可读且干净。请记住,它仅在Xcode 10+中有效,在撰写本文时,它处于Beta中。
Swift中很少涉及数组
创建数组
var stringArray = ["One", "Two", "Three", "Four"]
在数组中添加对象
stringArray = stringArray + ["Five"]
从索引对象获取价值
let x = stringArray[1]
追加对象
stringArray.append("At last position")
在索引处插入对象
stringArray.insert("Going", atIndex: 1)
移除物件
stringArray.removeAtIndex(3)
Concat对象值
var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
你可以那样做。首先确保Dog
数组中确实存在,然后将其删除。for
如果您认为Dog
数组中可能发生多次,请添加该语句。
var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"
for object in animals
{
if object == animalToRemove{
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
}
}
如果确定Dog
在数组中退出并且仅发生一次,请执行以下操作:
animals.removeAtIndex(animals.indexOf(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.removeAtIndex(array.indexOf(numberToRemove)!)
}
}
if object is String
{
// this will deal with strings
if object == animalToRemove
{
array.removeAtIndex(array.indexOf(animalToRemove)!)
}
}
}
如果您不知道要删除的元素的索引,并且该元素符合Equatable协议,则可以执行以下操作:
animals.removeAtIndex(animals.indexOf("dogs")!)
请参阅Equatable协议答案:如何做indexOfObject或适当的containsObject
使用索引数组删除元素:
字符串和索引数组
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"]
整数和索引数组
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]
使用另一个数组的元素值删除元素
整数数组
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
字符串数组
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"]
关于@Suragch的“删除未知索引的元素”的替代方案:
有一个更强大的“ indexOf(element)”版本,它将与谓词而不是对象本身匹配。它具有相同的名称,但由myObjects.indexOf {$ 0.property = valueToMatch}调用。它返回在myObjects数组中找到的第一个匹配项的索引。
如果该元素是一个对象/结构,则可能需要根据其属性之一的值删除该元素。例如,您有一个具有car.color属性的Car类,并且想要从carsArray中删除“红色”汽车。
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
可以预见的是,您可以通过将上面的if语句嵌入重复/循环循环中,并附加一个else块以将标志设置为“脱离”循环来删除“所有”红色汽车。
应该这样做(未经测试):
animals[2..3] = []
编辑:您需要将其设置为var
,而不是let
,否则它是一个不变的常量。
我想出了以下扩展名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.removeAtIndex(index)
}
}
var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]
var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
删除String对象的扩展
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
remove
返回已删除的元素:let animal = animals.remove(at: 2)