[swift-evolution] Proposal: Add a sequence-based initializer to Dictionary

Nicola Salmoria nicola.salmoria at gmail.com
Fri Jan 15 09:01:33 CST 2016


I'm ambivalent about the preconditionFailure. Since there would otherwise
be silent loss of data, I think it fits Swift's "safe by default" paradigm.
It's also consistent with what the normal initialization from a
DictionaryLiteral does.
However, I can also see how it might be more convenient to just pick the
last value.

Nicola

On Fri, Jan 15, 2016 at 11:53 AM, Alan Skipp <al_skipp at icloud.com> wrote:

> I’ve been absorbed in the world of Monoids lately, so I find the
> suggestion below to be particularly brilliant. : )
> It solves the issue of arbitrarily choosing the value for duplicate keys
> rather nicely. Only thing I’m not too sure about is the idea of failing by
> default on duplicate keys?
>
> On 15 Jan 2016, at 10:18, Nicola Salmoria via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> To handle the case of duplicate keys, why not allow to pass in a 'combine'
> function?
> The function could default to a preconditionFailure to be consistent with
> the DictionaryLiteral behavior, but be overridden by the caller as needed.
>
> extension Dictionary {
>     /// Creates a dictionary with the keys and values in the given
> sequence.
>     init<S: SequenceType where S.Generator.Element == Generator.Element>(_
> sequence: S, combine: (existing: Value, other: Value) -> Value = {
> preconditionFailure("Sequence contains duplicate keys"); return $1 } ) {
>         self.init()
>         for (key, value) in sequence {
>             if let existing = updateValue(value, forKey: key) {
>                 updateValue(combine(existing: existing, other: value),
> forKey: key)
>             }
>         }
>     }
> }
>
>
> usage examples:
>
> let samples = [("Rome", 40.2), ("New York", 35.1), ("Rome", 42.5), ("New
> York", 32.8)]
> let minTemperatures = Dictionary(samples, combine: min)
> // ["Rome": 40.2, "New York": 32.8]
> let maxTemperatures = Dictionary(samples, combine: max)
> // ["Rome": 42.5, "New York": 35.1]
>
> let probabilities = [("a", 0.25), ("b", 0.25), ("c", 0.25), ("a", 0.25)]
> let stateProbabilities = Dictionary(probabilities, combine: +)
> // ["b": 0.25, "a": 0.5, "c": 0.25]
>
>
> Nicola
>
>
> It’d be great if there was also an init that restricted the Values to
> Monoids, which would mean the combine function would be taken from the
> supplied Monoid values (I understand I’ve departed to fantasy island at
> this point, but one can dream : )
>
> Al
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160115/1e40a73f/attachment.html>


More information about the swift-evolution mailing list