Add modify…(…)
methods to Dictionary
/ MutableCollection
/ Optional
Full proposal text | Preliminary implementation
This proposal adds the following APIs to the Swift standard library:
-
Optional
:modifyIfNotNil(_:)
-
Dictionary
:modifyValue(forKey:_:)
modifyValue(forKey:default:_:)
-
MutableCollection
:modifyElement(at:_:)
The methods provide a no-surprises API for efficiently modifying a collection's specific value, preventing the user from accidentally triggering unwanted copy-on-write semantics, reducing the number of required key-lookups, while also making the user's intention clearer (i.e. "modify a value" vs. "get/remove a value, then insert a modified value").
Before
// only update optional's wrapped value, if not nil:
if var modifiedValue = valueOrNil {
// ...
valueOrNil = modifiedValue
}
// only update a dictionary's value if its keys exists:
if var modifiedValue = dictionary[key] {
// ...
dictionary[key] = modifiedValue
}
// update a dictionary's value, inserting a default value if its key doesn't yet exist:
var modifiedValue = dictionary[key] ?? …
// ...
dictionary[key] = modifiedValue
// update an array's element:
var modifiedElement = array[index]
// ...
array[index] = modifiedElement
After
// only update optional's wrapped value, if not nil:
valueOrNil.modifyIfNotNil { value in
// ...
}
// only update a dictionary's value if its keys exists:
dictionary.modifyValue(forKey: key) { value in
// ...
}
// update a dictionary's value, inserting a default value if its key doesn't yet exist:
dictionary.modifyValue(forKey: key, default: …) { value in
// ...
}
// update an array's element:
array.modifyElement(at: index) { value in
// ...
}
Note: The authors are well-aware of the
modify
subscript accessor and its short-circuiting capabilities, which cover 80% of the use-cases. This proposal aims to fill the remaining 20% by providing an API that covers all 100%.
Usage
To use this library in a Swift Package Manager project,
add the following to your Package.swift
file's dependencies:
.package(
url: "https://github.com/regexident/swift-evolution-modify-value.git",
.branch("master")
),
Full proposal text | Preliminary implementation
Thanks to @lorentey @anandabits, @DevAndArtist and @max_desiatov and everybody else who made helpful editorial suggestions.
Looking forward to reading your feedback on this draft proposal!