How can I unset/remove an element from an array in Apple's new language Swift?
Here's some code:
let animals = ["cats", "dogs", "chimps", "moose"]
How could the element animals[2]
be removed from the array?
How can I unset/remove an element from an array in Apple's new language Swift?
Here's some code:
let animals = ["cats", "dogs", "chimps", "moose"]
How could the element animals[2]
be removed from the array?
The let
keyword is for declaring constants that can't be changed. If you want to modify a variable you should use var
instead, e.g:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.remove(at: 2) //["cats", "dogs", "moose"]
A non-mutating alternative that will keep the original collection unchanged is to use filter
to create a new collection without the elements you want removed, e.g:
let pets = animals.filter { $0 != "chimps" }
Given
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"]
For only one element
if let index = animals.index(of: "chimps") {
animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]
For multiple elements
var animals = ["cats", "dogs", "chimps", "moose", "chimps"]
animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]
Or alternatively
animals.index(of: "chimps").map { animals.remove(at: $0) }
filter
) and return the element that was removed.dropFirst
or dropLast
to create a new array.Updated to Swift 3
The above answers seem to presume that you know the index of the element that you want to delete.
Often you know the reference to the object you want to delete in the array. (You iterated through your array and have found it, e.g.) In such cases it might be easier to work directly with the object reference without also having to pass everywhere its index. Hence, I suggest this solution. It uses the identity operator !==
, which you use to test whether two object references both refer to the same object instance.
func delete(element: String) {
list = list.filter() { $0 !== element }
}
Of course this doesn't just work for String
s.
Swift 5: Here is a cool and easy extension to remove elements in an array, without filtering :
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)
}
}
Usage :
var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"
myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]
Also works with other types, such as Int
since Element
is a generic type:
var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17
myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
For Swift4:
list = list.filter{$0 != "your Value"}
Few Operation relates to Array in Swift
Create Array
var stringArray = ["One", "Two", "Three", "Four"]
Add Object in Array
stringArray = stringArray + ["Five"]
Get Value from Index object
let x = stringArray[1]
Append Object
stringArray.append("At last position")
Insert Object at Index
stringArray.insert("Going", atIndex: 1)
Remove Object
stringArray.removeAtIndex(3)
Concat Object value
var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
You could do that. First make sure Dog
really exists in the array, then remove it. Add the for
statement if you believe Dog
may happens more than once on your array.
var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"
for object in animals
{
if object == animalToRemove{
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
}
}
If you are sure Dog
exits in the array and happened only once just do that:
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
If you have both, strings and numbers
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)!)
}
}
}
As of Xcode 10+, and according to the WWDC 2018 session 223, "Embracing Algorithms," a good method going forward will be mutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
Apple's example:
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."
see Apple's Documentation
So in the OP's example, removing animals[2], "chimps":
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
This method may be preferred because it scales well (linear vs quadratic), is readable and clean. Keep in mind that it only works in Xcode 10+, and as of writing this is in Beta.
If you don't know the index of the element that you want to remove, and the element is conform the Equatable protocol, you can do:
animals.removeAtIndex(animals.indexOf("dogs")!)
See Equatable protocol answer:How do I do indexOfObject or a proper containsObject
Remove elements using indexes array:
Array of Strings and indexes
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"]
Array of Integers and indexes
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]
Remove elements using element value of another array
Arrays of integers
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Arrays of 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"]
Regarding @Suragch's Alternative to "Remove element of unknown index":
There is a more powerful version of "indexOf(element)" that will match on a predicate instead of the object itself. It goes by the same name but it called by myObjects.indexOf{$0.property = valueToMatch}. It returns the index of the first matching item found in myObjects array.
If the element is an object/struct, you may want to remove that element based on a value of one of its properties. Eg, you have a Car class having car.color property, and you want to remove the "red" car from your carsArray.
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
Foreseeably, you could rework this to remove "all" red cars by embedding the above if statement within a repeat/while loop, and attaching an else block to set a flag to "break" out of the loop.
If you have array of custom Objects, you can search by specific property like this:
if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
doctorsInArea.removeAtIndex(index)
}
or if you want to search by name for example
if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
doctorsInArea.removeAtIndex(index)
}
Swift 5
guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)
This should do it (not tested):
animals[2..3] = []
Edit: and you need to make it a var
, not a let
, otherwise it's an immutable constant.
I came up with the following extension that takes care of removing elements from an Array
, assuming the elements in the Array
implement 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]
extension to remove String object
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
I use this extension, almost same as Varun's, but this one (below) is all-purpose:
extension Array where Element: Equatable {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}
To remove elements from an array, use the remove(at:)
,
removeLast()
and removeAll()
yourArray = [1,2,3,4]
Remove the value at 2 position
yourArray.remove(at: 2 )
Remove the last value from array
yourArray.removeLast()
Removes all members from the set
yourArray.removeAll()