Нет ли простого способа удалить определенный элемент из массива, если он равен заданной строке? Обходные пути - найти индекс элемента массива, который вы хотите удалить, а затем removeAtIndex
или создать новый массив, в котором вы добавите все элементы, которые не равны данной строке. Но нет ли более быстрого пути?
Удалить определенный элемент массива, равный строке - Swift
Ответ 1
Вы можете использовать filter() для фильтрации вашего массива следующим образом
var strings = ["Hello","Playground","World"]
strings = strings.filter{$0 != "Hello"}
print(strings) // "[Playground, World]"
редактировать/обновление:
Xcode 10 • Swift 4.2 или более поздняя версия
Вы можете использовать новый RangeReplaceableCollection
мутирования RangeReplaceableCollection
именем removeAll(where:)
var strings = ["Hello","Playground","World"]
strings.removeAll { $0 == "Hello" }
print(strings) // "[Playground, World]"
Если вам нужно удалить только первое вхождение элемента, мы могли бы реализовать собственный метод удаления в RangeReplaceableCollection
ограничив элементы до Equatable:
extension RangeReplaceableCollection where Element: Equatable {
@discardableResult
mutating func removeFirstElementEqual(to element: Element) -> Element? {
guard let index = firstIndex(of: element) else { return nil }
return remove(at: index)
}
}
Или используя предикат для неэквивалентных элементов:
extension RangeReplaceableCollection {
@discardableResult
mutating func removeFirstElement(where predicate: @escaping ((Element) -> Bool)) -> Element? {
guard let index = firstIndex(where: predicate) else { return nil }
return remove(at: index)
}
}
var strings = ["Hello","Playground","World"]
strings.removeFirstElementEqual(to: "Hello")
print(strings) // "[Playground, World]"
strings.removeFirstElement { $0 == "Playground" }
print(strings) // "[World]"
Ответ 2
Не понятно, если быстрее вы имеете в виду время выполнения или количество кода.
В последнем случае вы можете легко создать копию, используя метод filter
. Например, учитывая следующий массив:
let array = ["1", "2", "3", "4", "5"]
вы можете создать копию со всеми элементами, кроме "2", как:
let filteredArray = array.filter { $0 != "2" }
Ответ 3
Использование фильтра, как предложено выше, хорошо. Но если вы хотите удалить только одно вхождение значения или вы предполагаете, что в массиве нет дубликатов, и вам нужен более быстрый алгоритм, используйте это (в Swift3):
if let index = array.index(of: "stringToRemove") {
array.remove(at: index)
} else {
// not found
}
Ответ 4
Вы хотите использовать filter()
. Если у вас есть один элемент (называемый say obj
) для удаления, то предикат filter()
будет { $0 != obj }
. Если вы делаете это повторно для большого массива, это может быть проблемой производительности. Если вы можете отложить удаление отдельных объектов и хотите удалить всю подматрицу, используйте что-то вроде:
var stringsToRemove : [String] = ...
var strings : [String] = ...
strings.filter { !contains(stringsToRemove, $0) }
например:
1> ["a", "b", "c", "d"].filter { !contains(["b", "c"], $0) }
$R5: [String] = 2 values {
[0] = "a"
[1] = "d"
}
Ответ 5
Вы можете использовать filter() в сочетании с перегрузкой оператора для создания легко повторяемого решения:
func -= (inout left: [String], right: String){
left = left.filter{$0 != right}
}
var myArrayOfStrings:[String] = ["Hello","Playground","World"]
myArrayOfStrings -= "Hello"
print(myArrayOfStrings) // "[Playground, World]"
Ответ 6
если вам нужно удалить subArray из массива, это идеальное решение, используя Swift3:
var array = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
let subArrayToDelete = ["c", "d", "e", "ee"]
array = array.filter{ !subArrayToDelete.contains($0) }
print(array) // ["a", "b", "f", "g", "h", "i", "j"]
это лучше для вашей производительности, а не для удаления по одному.
btw даже быстрее решение (но оно будет переупорядочивать элементы в конечном массиве):
array = Array(Set(array).subtracting(subArrayToDelete))