Як я можу зняти / видалити елемент із масиву в новій мові Swift від Apple?
Ось код:
let animals = ["cats", "dogs", "chimps", "moose"]
Як елемент animals[2]
можна було видалити з масиву?
Як я можу зняти / видалити елемент із масиву в новій мові Swift від Apple?
Ось код:
let animals = ["cats", "dogs", "chimps", "moose"]
Як елемент animals[2]
можна було видалити з масиву?
Відповіді:
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+ та відповідно до сеансу 223 WWDC 2018, "Прийняття алгоритмів", хорошим методом буде наступний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."
Так у прикладі ОП видалення тварин [2], "шимпанзе":
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
Цей спосіб може бути кращим, оскільки він добре масштабує (лінійний проти квадратичний), читабельний і чистий. Майте на увазі, що він працює лише в Xcode 10+, а на момент написання - це в Beta.
Деякі операції стосуються масиву в Swift
Створити масив
var stringArray = ["One", "Two", "Three", "Four"]
Додати об’єкт у масив
stringArray = stringArray + ["Five"]
Отримати значення від об’єкта Index
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 або належний файл міститьObject
Видаліть елементи за допомогою масиву індексів:
Масив рядків та індексів
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, і ви хочете вилучити "червоний" автомобіль зі своїх автомобілів.
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
Передбачувано ви можете переробити це, щоб вилучити "всі" червоні машини, вставивши вище, якщо заява в циклі повторення / в той час, і додавши ще один блок, щоб встановити прапор, щоб "вирватися" з циклу.
Якщо у вас є масив користувацьких об’єктів, ви можете шукати за конкретною властивістю, наприклад, ця:
if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
doctorsInArea.removeAtIndex(index)
}
або якщо ви хочете, наприклад, шукати по імені
if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
doctorsInArea.removeAtIndex(index)
}
Це слід зробити (не перевірено):
animals[2..3] = []
Редагувати: і вам потрібно зробити це a var
, а не a 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 }
}
}
Я використовую це розширення, майже те саме, що і Varun, але це (нижче) універсальне:
extension Array where Element: Equatable {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}
remove
повертає вилучений елемент:let animal = animals.remove(at: 2)