How do I merge so that the newer value wins, when ':~:' always keeps the value already set?
← Operators and Expressions · Ref: Q1410
Write your own function. ':~:' means one thing on every built-in type - it never overwrites a set value and fills whatever is unset or missing - and that is not configurable. When you need a different policy, say so in a function whose name states it.
NEWER WINS FOR A WHOLE VALUE
For a single value use ':=:' (copy) or ':^:' (replace) - they overwrite.
NEWER WINS, KEY BY KEY
Walk the source and assign each entry. For a Dict, 'dict += DictEntry(key, value)' replaces the value under an existing key:
newerWins()
->
target as Dict of (String, Integer)
source as Dict of (String, Integer)
for entry in source
target += entry
COMBINE VALUES
To add numbers rather than keep the first, stream them: 'cat values > total' sums, because streaming into a value is a fold, not a merge.
See Q1405 for the merge rule on single values. See Q1406 for gathering partial results with ':~:'. See Q1058 for copy, replace and merge.
Example
defines module qa.operators.mergecustombehaviour defines function newerWins() -> target as Dict of (String, Integer) source as Dict of (String, Integer) for entry in source target += entry defines program MergeCustomBehaviourDemo() stdout <- Stdout() current <- {"cpu": 1, "disk": 7} update <- {"cpu": 4, "ram": 8} //The built-in merge keeps what is already set merged <- {"cpu": 1, "disk": 7} merged :~: update stdout.println(`merge keeps: ${merged}`) //A named function says the newer value wins newerWins(current, update) stdout.println(`newer wins: ${current}`) //Streaming into a value folds - here it sums total <- Integer() cat [4, 8, 3] > total stdout.println(`summed: ${total}`)
Other ways to ask this
- Can I make ':~:' overwrite existing values?
- How do I merge two Dicts where the second one wins?
- How do I add numbers together when merging instead of keeping the first?
- What do I use when the built-in merge rule is not what I need?
Coming from another language?
Java: Map.merge(key, value, remappingFunction) lets every call choose its own policy. Python: dict.update lets the newer win. EK9: ':~:' has one fixed meaning (first recorded wins, fill the gaps); any other policy is an ordinary, named function.
Keywords: custom merge, merge, newer wins, remapping function, :~:, overwrite, merge policy