Cách xóa phần tử khỏi một mảng trong Swift


236

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:


300

Các lettừ 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 varthay 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" }

7
FYI: removetrả về phần tử bị xóa:let animal = animals.remove(at: 2)
Tải 2

1
chúng ta chỉ có thể lọc dựa trên chỉ số ??
shaqir sai

@shaqirsaiyed Bạn có thể lọc bất kỳ vị ngữ nào bạn có thể nghĩ ra. ví dụ: bạn có thể lọc tất cả các động vật kết thúc bằng "s".
Womble

thêm động vật = thú cưng
Puji Wahono

197

Được

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

Xóa phần tử đầu tiên

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

Xóa phần tử cuối cùng

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

Xóa phần tử tại chỉ mục

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

Xóa phần tử của chỉ mục không xác định

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"]

Ghi chú

  • Các phương thức trên sửa đổi mảng tại chỗ (ngoại trừ filter) và trả về phần tử đã bị xóa.
  • Hướng dẫn Swift về Bộ lọc bản đồ Giảm
  • Nếu bạn không muốn sửa đổi mảng ban đầu, bạn có thể sử dụng dropFirsthoặc dropLasttạo một mảng mới.

Đã cập nhật lên Swift 5.2


Cảm ơn những ví dụ này, trong bạn Xóa phần tử của chỉ mục không xác định > cho nhiều phần tử , bạn sẽ viết phần đóng nào để xóa chimps && moose? Tôi đang tìm kiếm một cái gì đó khác với{$0 != "chimps" && $0 != "moose"}

161

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 Strings.


23
Nên làlist = list.filter({ $0 != element })
Craig Grummitt

5
Không nếu bạn muốn kiểm tra với toán tử nhận dạng.
Daniel

3
array.indexOf({ $0 == obj })
JRC

2
Lưu ý nếu các đối tượng khác tham chiếu listviệ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.
Crashalot

1
Mô hình lập trình chức năng dựa vào các đối tượng bất biến. Tức là bạn không thay đổi chúng. Thay vào đó, bạn tạo một đối tượng mới. Đây là những gì xóa, bản đồ, giảm, vv. danh sách sẽ là một đối tượng mới được tạo. Trong đoạn mã trên tôi đang gán lại để liệt kê một đối tượng mới được tạo. Điều đó làm việc cho tôi, bởi vì tôi thiết kế mã của mình theo cách lập trình theo chức năng.
Daniel

44

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ư Inttừ Elementlà một kiểu generic:

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

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

1
Thú vị với mảng này trong đó Element: Phần tương đương
Nicolas Manzini

1
Xuất sắc. Mặc dù nó không hoạt động nếu bạn bắt đầu với một danh sách các Giao thức, vì - Loại giao thức không thể tuân theo 'Tương đương' vì chỉ các loại cụ thể mới có thể tuân thủ các giao thức :-(
AW101

22

Dành cho Swift4:

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

15

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."

xem Tài liệu của Apple

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.


remove ALL (nơi :) sẽ chỉ có thể trong swift 4.2
Vlad Pulichev

14

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])"

14

Bạn có thể làm điều đó. Trước tiên hãy chắc chắn rằng Dogthực sự tồn tại trong mảng, sau đó loại bỏ nó. Thêm forcâu lệnh nếu bạn tin rằng Dogcó 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 Dogthoá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 mảng của tôi không chứa Chuỗi thì sao?
Apqu

@apqu đã làm một bản cập nhật khác '|| đối tượng == Int () 'và' || object == String () 'là không cần thiết
GuiSoySauce

lặp một mảng đi lại hiệu quả. kiểm tra .filter, .compactMap
MLBDG


10

Xóa các phần tử bằng mảng chỉ mục:

  1. 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"]
  2. 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

  1. 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]
  2. 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"]

4
Đây là một câu trả lời lót và nó rất hiệu quả để mã hóa tốt hơn và thực hiện nhanh.
iOSDev

Xin chào @Krunal - câu trả lời tuyệt vời, bạn có thể xem câu hỏi sau (phát hành hình ảnh từ một mảng hình ảnh): stackoverflow.com/questions/47735975/ Lỗi
Lập trình viên máy chủ

6

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.


6

Swift 5

guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)

4

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)
    }

3

Đ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 varchứ không phải letlà một hằng số bất biến.


5
Khi sử dụng phạm vi (phụ) của một mảng hiện có để tạo một mảng khác, phạm vi cần phải có 3 dấu chấm. Trên đây nên được viết là động vật [2 ... 3]
zevij

3

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 Arraythự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)
  }

}

Sử dụng:

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

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

Xin chào @nburk - câu trả lời tuyệt vời, bạn có thể xem câu hỏi sau (phát hành hình ảnh từ một mảng hình ảnh): stackoverflow.com/questions/47735975/ Lỗi
Lập trình viên máy chủ

1

mở rộng để loại bỏ đối tượng String

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

ép buộc có thể gây ra sự cố, tôi nghĩ bạn nên tránh nó trong trường hợp này.
dùng3206558

Func "đột biến" là gì?
AwesomeElephant8232

nó được sử dụng để nói rằng hàm này sẽ thay đổi tự (mảng).
Varun Naharia

1

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 }
        }
    }

1

Để loại bỏ các phần tử khỏi một mảng, sử dụng remove(at:), removeLast()removeAll().

yourArray = [1,2,3,4]

Xóa giá trị ở 2 vị trí

yourArray.remove(at: 2)

Xóa giá trị cuối cùng khỏi mảng

yourArray.removeLast()

Xóa tất cả các thành viên khỏi tập hợp

yourArray.removeAll()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.