Làm cách nào tôi có thể hủy / xóa phần tử khỏi một mảng trong ngôn ngữ mới của Apple Swift?
Đây là một số mã:
let animals = ["cats", "dogs", "chimps", "moose"]
Làm thế nào các phần tử animals[2]
có thể được loại bỏ khỏi mảng?
Làm cách nào tôi có thể hủy / xóa phần tử khỏi một mảng trong ngôn ngữ mới của Apple Swift?
Đây là một số mã:
let animals = ["cats", "dogs", "chimps", "moose"]
Làm thế nào các phần tử animals[2]
có thể được loại bỏ khỏi mảng?
Câu trả lời:
Các let
từ khóa là kê khai hằng mà không thể thay đổi. Nếu bạn muốn sửa đổi một biến bạn nên sử dụng var
thay thế, ví dụ:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.remove(at: 2) //["cats", "dogs", "moose"]
Một thay thế không biến đổi sẽ giữ cho bộ sưu tập ban đầu không thay đổi là sử dụng filter
để tạo một bộ sưu tập mới mà không cần loại bỏ các yếu tố bạn muốn, ví dụ:
let pets = animals.filter { $0 != "chimps" }
Được
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"]
Chỉ một yếu tố
if let index = animals.firstIndex(of: "chimps") {
animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]
Đối với nhiều yếu tố
var animals = ["cats", "dogs", "chimps", "moose", "chimps"]
animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]
filter
) và trả về phần tử đã bị xóa.dropFirst
hoặc dropLast
tạo một mảng mới.Đã cập nhật lên Swift 5.2
Các câu trả lời ở trên dường như cho rằng bạn biết chỉ số của phần tử mà bạn muốn xóa.
Thường thì bạn biết tham chiếu đến đối tượng bạn muốn xóa trong mảng. (Bạn đã lặp qua mảng của mình và đã tìm thấy nó, vd) Do đó, tôi đề nghị giải pháp này. Nó sử dụng toán tử nhận dạng !==
mà bạn sử dụng để kiểm tra xem hai tham chiếu đối tượng có tham chiếu đến cùng một thể hiện đối tượng hay không.
func delete(element: String) {
list = list.filter() { $0 !== element }
}
Tất nhiên điều này không chỉ làm việc cho String
s.
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
list
việc xóa này sẽ không cập nhật các tham chiếu mảng khác vì bạn đang gán một mảng mới list
. Chỉ là một hàm ý tinh tế nếu bạn xóa khỏi mảng với phương pháp này.
Swift 5: Đây là một phần mở rộng thú vị và dễ dàng để loại bỏ các phần tử trong một mảng, mà không cần lọc:
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)
}
}
Sử dụng :
var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"
myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]
Cũng làm việc với các loại khác, chẳng hạn như Int
từ Element
là một kiểu generic:
var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17
myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
Dành cho Swift4:
list = list.filter{$0 != "your Value"}
Kể từ Xcode 10+, và theo phiên WWDC 2018 phiên bản 223, "Thuật toán ôm ấp", một phương pháp tốt sẽ được chuyển tiếpmutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
Ví dụ của 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."
Vì vậy, trong ví dụ của OP, loại bỏ động vật [2], "tinh tinh":
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
Phương pháp này có thể được ưa thích vì nó có tỷ lệ tốt (tuyến tính so với bậc hai), có thể đọc và sạch. Hãy nhớ rằng nó chỉ hoạt động trong Xcode 10+ và khi viết bài này là bản Beta.
Rất ít hoạt động liên quan đến Array trong Swift
Tạo mảng
var stringArray = ["One", "Two", "Three", "Four"]
Thêm đối tượng trong mảng
stringArray = stringArray + ["Five"]
Nhận giá trị từ đối tượng Index
let x = stringArray[1]
Nối đối tượng
stringArray.append("At last position")
Chèn đối tượng tại Index
stringArray.insert("Going", atIndex: 1)
Xóa đối tượng
stringArray.removeAtIndex(3)
Giá trị đối tượng concat
var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
Bạn có thể làm điều đó. Trước tiên hãy chắc chắn rằng Dog
thực sự tồn tại trong mảng, sau đó loại bỏ nó. Thêm for
câu lệnh nếu bạn tin rằng Dog
có thể xảy ra nhiều hơn một lần trên mảng của bạn.
var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"
for object in animals
{
if object == animalToRemove{
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
}
}
Nếu bạn chắc chắn Dog
thoát trong mảng và chỉ xảy ra một lần chỉ cần làm điều đó:
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
Nếu bạn có cả hai, chuỗi và số
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)!)
}
}
}
Nếu bạn không biết chỉ mục của thành phần mà bạn muốn xóa và thành phần đó tuân thủ giao thức Equitable, bạn có thể thực hiện:
animals.removeAtIndex(animals.indexOf("dogs")!)
Xem câu trả lời giao thức tương đương: Làm thế nào để tôi thực hiện indexOfObject hoặc một hàm chứaObject thích hợp
Xóa các phần tử bằng mảng chỉ mục:
Mảng của chuỗi và chỉ mục
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"]
Mảng số nguyên và chỉ mục
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]
Xóa các phần tử bằng giá trị phần tử của mảng khác
Mảng số nguyên
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Mảng dây
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"]
Về @ Suragch's Thay thế cho "Xóa phần tử của chỉ mục không xác định":
Có một phiên bản "indexOf (phần tử)" mạnh hơn sẽ khớp với một vị ngữ thay vì chính đối tượng. Nó có cùng tên nhưng được gọi bởi myObjects.indexOf {$ 0.property = valueToMatch}. Nó trả về chỉ mục của mục phù hợp đầu tiên được tìm thấy trong mảng myObjects.
Nếu phần tử là một đối tượng / struct, bạn có thể muốn xóa phần tử đó dựa trên giá trị của một trong các thuộc tính của nó. Ví dụ: bạn có một lớp Xe có thuộc tính car.color và bạn muốn xóa chiếc xe "đỏ" khỏi xe ô tô của mình.
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
Có thể thấy trước, bạn có thể làm lại điều này để loại bỏ "tất cả" ô tô màu đỏ bằng cách nhúng câu lệnh if ở trên trong vòng lặp lặp / lặp và gắn một khối khác để đặt cờ "thoát" khỏi vòng lặp.
Nếu bạn có mảng Đối tượng tùy chỉnh, bạn có thể tìm kiếm theo thuộc tính cụ thể như thế này:
if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
doctorsInArea.removeAtIndex(index)
}
hoặc nếu bạn muốn tìm kiếm theo tên chẳng hạn
if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
doctorsInArea.removeAtIndex(index)
}
Điều này nên làm điều đó (không được thử nghiệm):
animals[2..3] = []
Chỉnh sửa: và bạn cần biến nó thành một var
chứ không phải let
là một hằng số bất biến.
Tôi đã đưa ra phần mở rộng sau đây có nhiệm vụ loại bỏ các phần tử khỏi một Array
, giả sử các phần tử trong phần Array
thực hiện 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]
mở rộng để loại bỏ đối tượng String
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
Tôi sử dụng tiện ích mở rộng này, gần giống như của Varun, nhưng tiện ích mở rộng này (bên dưới) là tất cả mục đích:
extension Array where Element: Equatable {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}
remove
trả về phần tử bị xóa:let animal = animals.remove(at: 2)