Como posso desmarcar / remover um elemento de uma matriz no novo idioma Swift da Apple?
Aqui está um código:
let animals = ["cats", "dogs", "chimps", "moose"]
Como o elemento pode animals[2]
ser removido da matriz?
Como posso desmarcar / remover um elemento de uma matriz no novo idioma Swift da Apple?
Aqui está um código:
let animals = ["cats", "dogs", "chimps", "moose"]
Como o elemento pode animals[2]
ser removido da matriz?
Respostas:
A let
palavra-chave é para declarar constantes que não podem ser alteradas. Se você deseja modificar uma variável, você deve usar var
, por exemplo:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.remove(at: 2) //["cats", "dogs", "moose"]
Uma alternativa não mutante que manterá a coleção original inalterada é usar filter
para criar uma nova coleção sem os elementos que você deseja remover, por exemplo:
let pets = animals.filter { $0 != "chimps" }
Dado
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"]
Para apenas um elemento
if let index = animals.firstIndex(of: "chimps") {
animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]
Para vários elementos
var animals = ["cats", "dogs", "chimps", "moose", "chimps"]
animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]
filter
) e retornam o elemento que foi removido.dropFirst
ou dropLast
criar uma nova matriz.Atualizado para o Swift 5.2
As respostas acima parecem presumir que você conhece o índice do elemento que deseja excluir.
Muitas vezes, você conhece a referência ao objeto que deseja excluir na matriz. (Você iterou na sua matriz e a encontrou, por exemplo). Nesses casos, pode ser mais fácil trabalhar diretamente com a referência do objeto sem precisar passar em todo lugar seu índice. Por isso, sugiro esta solução. Ele usa o operador de identidade !==
, usado para testar se duas referências a objetos se referem à mesma instância de objeto.
func delete(element: String) {
list = list.filter() { $0 !== element }
}
Claro que isso não funciona apenas para String
s.
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
list
essa exclusão não atualizarão as outras referências de matriz, pois você está atribuindo uma nova matriz list
. Apenas uma implicação sutil se você excluir de matrizes com essa abordagem.
Swift 5: Aqui está uma extensão fácil e legal para remover elementos em uma matriz, sem filtrar:
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)
}
}
Uso:
var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"
myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]
Também funciona com outros tipos, como Int
since Element
é um tipo genérico:
var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17
myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
Para Swift4:
list = list.filter{$0 != "your Value"}
A partir do Xcode 10+, e de acordo com a sessão 223 da WWDC 2018, "Abraçando algoritmos", um bom método daqui para frente serámutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
Exemplo da 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."
consulte a documentação da Apple
Assim, no exemplo do OP, removendo animais [2], "chimps":
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
Esse método pode ser preferido porque ele escala bem (linear versus quadrático), é legível e limpo. Lembre-se de que ele só funciona no Xcode 10+ e, por escrito, isso está na versão beta.
Poucas operações estão relacionadas à matriz no Swift
Criar matriz
var stringArray = ["One", "Two", "Three", "Four"]
Adicionar objeto na matriz
stringArray = stringArray + ["Five"]
Obter valor do objeto Index
let x = stringArray[1]
Anexar Objeto
stringArray.append("At last position")
Inserir objeto no índice
stringArray.insert("Going", atIndex: 1)
Remover Objeto
stringArray.removeAtIndex(3)
Valor do objeto Concat
var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
Você poderia fazer isso. Primeiro verifique se Dog
realmente existe na matriz e remova-a. Adicione a for
declaração se você acredita que isso Dog
pode acontecer mais de uma vez na sua matriz.
var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"
for object in animals
{
if object == animalToRemove{
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
}
}
Se você tem certeza de que as Dog
saídas na matriz ocorreram apenas uma vez, faça isso:
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
Se você tiver ambos, strings e números
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)!)
}
}
}
Se você não conhece o índice do elemento que deseja remover e o elemento está em conformidade com o protocolo Equatable, é possível:
animals.removeAtIndex(animals.indexOf("dogs")!)
Consulte Resposta do protocolo equivalente: Como faço para indexOfObject ou um containsObject adequado
Remova os elementos usando a matriz de índices:
Matriz de strings e índices
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"]
Matriz de números inteiros e índices
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]
Remover elementos usando o valor do elemento de outra matriz
Matrizes de números inteiros
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Matrizes de strings
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"]
Em relação à alternativa de @ Suragch para "Remover elemento de índice desconhecido":
Existe uma versão mais poderosa do "indexOf (elemento)" que corresponderá a um predicado em vez do próprio objeto. Ele tem o mesmo nome, mas é chamado por myObjects.indexOf {$ 0.property = valueToMatch}. Retorna o índice do primeiro item correspondente encontrado na matriz myObjects.
Se o elemento for um objeto / estrutura, convém remover esse elemento com base no valor de uma de suas propriedades. Por exemplo, você tem uma classe Car com a propriedade car.color e deseja remover o carro "vermelho" do carsArray.
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
Previsivelmente, você poderia refazer isso para remover "todos" os carros vermelhos incorporando a instrução if acima em um loop de repetição / while e anexando um bloco else para definir uma bandeira para "sair" do loop.
Se você tiver uma matriz de objetos personalizados, poderá pesquisar por propriedade específica como esta:
if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
doctorsInArea.removeAtIndex(index)
}
ou se você deseja pesquisar por nome, por exemplo
if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
doctorsInArea.removeAtIndex(index)
}
Isso deve ser feito (não testado):
animals[2..3] = []
Edit: e você precisa torná-lo um var
, não um let
, caso contrário, é uma constante imutável.
Eu vim com a seguinte extensão que cuida da remoção de elementos de um Array
, assumindo os elementos no Array
implemento 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]
extensão para remover o objeto String
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
Eu uso essa extensão, quase a mesma da Varun, mas essa (abaixo) é para todos os fins:
extension Array where Element: Equatable {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}
remove
retorna o elemento removido:let animal = animals.remove(at: 2)