fswarbrick
(Frank Swarbrick)
1
I currently have the following:
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]
1 Like
fswarbrick
(Frank Swarbrick)
3
That works perfectly!
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:
record[keyPath: property] = record[keyPath: property].map { … }
1 Like
fswarbrick
(Frank Swarbrick)
5
Found the old thread: Proposal: "inout" in for loops. From 2015. Seems like it should have made stdlib by now...
It touches on something we want to do as part of the ownership manifesto. Look for the section on for loops.
That would be built into the language (as exposed by adoption of certain standard protocols, of course).
8 Likes
fswarbrick
(Frank Swarbrick)
7
Looks good. Let's do it! :-)