As @i40West points out, removeLast is essentially a pop. That said, if you wanted to fix the compiler issues with the original code:
The array might not contain class references so
AnyObjectwouldn’t work. You could replace that withAny(which can contain classes, structs or enums), but better to return anElement, which is what an instance ofArraytypealiases for whatever it actually contains.self.lastreturns an optional (in case the array is empty). You could choose to return an optional frompopsimilar tolast, or just assert if the array is empty similar toremoveLast.Since
popis modifyingself(it removes an entry) andArrayis a struct, you need to mark the function asmutating.
So the full version, assuming removeLast didn’t return a value, could be something like:
extension Array {
mutating func pop() -> Element {
precondition(self.startIndex != self.endIndex, "Attempt to pop from an empty array")
let out = self.last
self.removeLast()
return out!
}
}
Answer from Airspeed Velocity on Stack OverflowAs @i40West points out, removeLast is essentially a pop. That said, if you wanted to fix the compiler issues with the original code:
The array might not contain class references so
AnyObjectwouldn’t work. You could replace that withAny(which can contain classes, structs or enums), but better to return anElement, which is what an instance ofArraytypealiases for whatever it actually contains.self.lastreturns an optional (in case the array is empty). You could choose to return an optional frompopsimilar tolast, or just assert if the array is empty similar toremoveLast.Since
popis modifyingself(it removes an entry) andArrayis a struct, you need to mark the function asmutating.
So the full version, assuming removeLast didn’t return a value, could be something like:
extension Array {
mutating func pop() -> Element {
precondition(self.startIndex != self.endIndex, "Attempt to pop from an empty array")
let out = self.last
self.removeLast()
return out!
}
}
I don't think you should use AnyObject. Have you learned generics? Try:
extension Array
{
func pop() -> T
{
let out = self.last
self.removeLast()
return out
}
}
how to remove an item from a list based on the item's shallow reference?
removing from an array inside a function – Swift – Hacking with Swift forums
How do I remove an item from an array?
How to remove an element from an array in Swift - Stack Overflow
I tried to find a simple code snippet, but only found the remove at: method which
relies on knowing the item's position in the list.
the built in method should exist I just can't seem to find it.
mean while I'm relying on the === operator iterating through the whole list which feels like an unprofessional MacGyverism.
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"]
Remove first element
animals.removeFirst() // "cats"
print(animals) // ["dogs", "chimps", "moose"]
Remove last element
animals.removeLast() // "moose"
print(animals) // ["cats", "dogs", "chimps"]
Remove element at index
animals.remove(at: 2) // "chimps"
print(animals) // ["cats", "dogs", "moose"]
Remove element of unknown index
For only one element
if let index = animals.firstIndex(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"]
Notes
- The above methods modify the array in place (except for
filter) and return the element that was removed. - Swift Guide to Map Filter Reduce
- If you don't want to modify the original array, you can use
dropFirstordropLastto create a new array.
Updated to Swift 5.2
Hello so I have an observable object class containing an array, and button in my view that adds to that array just fine, however I’m having trouble figuring out a way to have each element in the array, have its own button that removes it,
I’ve been able to render it, but as far as the actual button action, I can’t quite understand the syntax to remove the correct index in the array.
Use removeSubrange method of array. Make a valid range by element location and length.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let range = 1...3
array.removeSubrange(range)
print(array)
Output: [1, 5, 6, 7, 8, 9, 10]
Note: Range should be a valid range I mean it should not be out from array.
Here is yours way (by for loop) We can not remove objects by their indexes in a loop because every time object removes array's count and objects indexes will be change so out of range crash can come or you might get a wrong output. So you will have to take help of another array. See below example:-
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var newArray: [Int] = []
let minRange = 1
let maxRange = 3
for i in 0..<array.count {
if i >= minRange && i <= maxRange {
/// Avoid
continue
}
newArray.append(array[i])
}
print(newArray)
Output: [1, 5, 6, 7, 8, 9, 10]
If you want to remove items by index in a range you have to inverse the indexes to start with the highest index otherwise you will get the out-of-range exception. Consider also that indexes are zero-based.
That's a safe version which checks also the upper bound of the array.
var array = [1, 2, 3, 4, 5, 6]
for i in (0...3).reversed() where i < array.count {
array.remove(at: i)
}
print(array) // [5, 6]
You can find a more generic and more efficient solution here