Удалить конкретный элемент массива, равный String-Swift


Нет ли простого способа удалить определенный элемент из массива, если он равен заданной строке? Обходные пути состоят в том, чтобы найти индекс элемента массива, который вы хотите удалить, а затем removeAtIndex, или создать новый массив, в который вы добавляете все элементы, которые не равны данной строке. Но разве нет более быстрого способа?

6 40

6 ответов:

Вы можете использовать filter() для фильтрации массива следующим образом

var strings = ["Hello","Playground","World"]

strings = strings.filter{$0 != "Hello"}

print(strings)   // "[Playground, World]"

Изменить / обновить:

Xcode 10 * Swift 4.2

Вы можете использовать новый метод мутации RangeReplaceableCollection removeAll(where:)

var strings = ["Hello","Playground","World"]

strings.removeAll { $0 == "Hello" }

print(strings)   // "[Playground, World]"

Неясно, если под более быстрым вы подразумеваете время выполнения или объем кода.

В последнем случае вы можете легко создать копию, используя метод filter. Например, задан следующий массив:
let array = ["1", "2", "3", "4", "5"]

Вы можете создать копию со всеми элементами, кроме "2", как:

let filteredArray = array.filter { $0 != "2" }

Вы захотите использовать 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"
}

Использование фильтра, как предложено выше, хорошо. Но если вы хотите удалить только одно вхождение значения или предполагаете, что в массиве нет дубликатов, и вам нужен более быстрый алгоритм, используйте это (в Swift3):

if let index = array.index(of: "stringToRemove") {
    array.remove(at: index)
} else {
    // not found
}

Вы можете использовать filter () в сочетании с перегрузкой оператора для получения легко воспроизводимого решения :

func -= (inout left: [String], right: String){
    left = left.filter{$0 != right}    
}

var myArrayOfStrings:[String] = ["Hello","Playground","World"]

myArrayOfStrings -= "Hello"

print(myArrayOfStrings)   // "[Playground, World]"

Если вам нужно удалить подмножество из массива, то это идеальное решение с помощью 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"]

Это лучше для вашей производительности, а не удаление по одному.

Кстати даже быстрее решение есть (но оно будет переставлять элементы в конечном массиве):

array = Array(Set(array).subtracting(subArrayToDelete))