for i in record[keyPath: property].startIndex ..< record[keyPath: property].endIndex {
let (lower, upper) = (start, start + len)
start = upper // next start
if let value = Value(buffer: buffer[lower ..< upper], conversionOptions: options) {
record[keyPath: property][i] = value
}
}
(Hopefully understandable given lack of full context).
Is there any way to avoid using explicit subscripting yet still be able to mutate the value of the Array referred to by record[keyPath: property]?
I tried this:
for var element in record[keyPath: property] {
let (lower, upper) = (start, start + len)
start = upper // next start
if let value = Value(buffer: buffer[lower ..< upper], conversionOptions: options) {
element = value
}
}
But element is only a copy of the actual element, and thus the actual array element is not mutated.
IIRC there was a thread that discussed a method that can mutate each element of a mutable collection, but please search for that thread on your own (I don't have time to do it).
Here is a quick function that I wrote to showcase how you could workaround your issue nicely:
var test = [0, 1]
extension MutableCollection {
mutating func updateEach(_ update: (inout Element) -> Void) {
for i in indices {
update(&self[i])
}
}
}
test.updateEach {
if $0 == 1 {
$0 = 42
}
}
print(test) // [0, 42]
record[keyPath: property].updateEach { element in
let (lower, upper) = (start, start + len)
start = upper // next start
if let value = Value(buffer: buffer[lower ..< upper], conversionOptions: options) {
element = value
}
}
I wonder why its not in the standard library. Is it somehow considered "bad practice"? I'll see if I can find the other thread that discusses it.
updateEach is fundamentally an in-place map, which I think would be a great addition to the standard library. Whether the closure should be (inout Element) -> Void or Element -> Element is one major question. For now, you could implement this as something like: