Is it possible to do "get and remove first element of array" in one go?
var items: [String] = ...
....
var first: String?
if !items.isEmpty {
first = items.removeFirst()
}
Is it possible to do "get and remove first element of array" in one go?
var items: [String] = ...
....
var first: String?
if !items.isEmpty {
first = items.removeFirst()
}
I don't think so, but if you need to call this function repeatedly, e.g. in parsing, you could perhaps first turn your array into an ArraySlice
and then use .popFirst()
. Since the slice keeps the underlying collection and only does simple bookkeeping of start and end indices, the function is super cheap.
var slice = items[...]
let first = slice.popFirst()
Did you try it? Your example pretty much works as is (see removeFirst()), though it is inefficient to do it this way rather than using slices as @sveinhal suggests (in particular, you are likely to create accidentally quadratic algorithms your way).
In this particular case of mine quadratic/cubic/etc behaviour is non issue (N is a very small number), my main concern is having to write the check and the operation separately (extra line count + non atomicity). I hoped there was a built-in operation to that account. I'm also missing "find and remove first element matching criteria". Simulating it now with:
var item: String?
if let index = items.firstIndex(where: { it in ... }) {
item = items[index]
items.remove(at: index)
}
Edit:
I realised I also need a version of removeFirst that passes both element and index in its predicate parameter. Doing this now:
extension Array {
mutating func removeFirstElement2(where predicate: (Element, Int) -> Bool) -> Element? {
for i in 0 ..< count {
let element = self[i]
if predicate(element, i) {
remove(at: i)
return element
}
}
return nil
}
}
Is there any better (e.g., more functional) way?
"removeFirst()" / "removeFirst(where:...)" calls returning Optional would be perfect.
One thing to watch out for with the removeX
methods is that they don’t preserve indices:
var a = ["Hello", "Cruel", "World!"]
let i = a.firstIndex(of: "Cruel")!
a.removeFirst()
print(a[i]) // World!
Contrast:
let a = ["Hello", "Cruel", "World!"]
var aS = a[...]
let i = aS.firstIndex(of: "Cruel")!
aS.popFirst()
print(aS[i]) // Cruel
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple