> On Feb 19, 2017, at 11:22 AM, Ole Begemann <o...@oleb.net> wrote: > > >> On 17 Feb 2017, at 01:26, Ben Cohen via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> Here is a list of commonly requested changes/enhancements to Dictionary, all >> of which would probably be appropriate to put together into a single >> evolution proposal: >> >> init from/merge in a Sequence of Key/Value pairs (already raised as SE-100: >> https://github.com/apple/swift-evolution/blob/master/proposals/0100-add-sequence-based-init-and-merge-to-dictionary.md >> >> <https://github.com/apple/swift-evolution/blob/master/proposals/0100-add-sequence-based-init-and-merge-to-dictionary.md>). >> make the Values view collection a MutableCollection (as in this PR: >> https://github.com/apple/swift-evolution/pull/555 >> <https://github.com/apple/swift-evolution/pull/555>). >> Add a defaulting subscript get (e.g. counts[key, default: 0] += 1 or >> grouped(key, default:[]].append(value)). >> Add a group by-like init to create a Dictionary<K,[V]> from a sequence of V >> and a closure (V)->K. > Out of interest, how would you implement this? Does it require a generics > feature that's slated for Swift 4? I tried two approaches that don't compile > in a current Swift 3.1 snapshot (and I'm getting a segfault with both > examples in a dev snapshot from 2017-02-14): > > 1) > > extension Dictionary { > // error: same-type constraint 'Value' == '[S.Iterator.Element]' is > recursive > init<S: Sequence>(values: S, groupedBy: (S.Iterator.Element) -> Key) > where Value == [S.Iterator.Element] { > ... > } > } > } > > 2) > > // error: reference to generic type 'Array' requires arguments in <...> > extension Dictionary where Value == Array { > init<S: Sequence>(values: S, groupedBy: (S.Iterator.Element) -> Key) > where S.Iterator.Element == Value.Element { > ... > } > } > } >
Oops, looks like a bug in the same-type constraint implementation. Ought to work in 3.1. Minimal crasher repro: extension Array { func f<S: Sequence>() where Element == S.Iterator.Element? { } } I’ve raised https://bugs.swift.org/browse/SR-4008 It ought to be done with the first one. For the second, you can’t constrain Value == Array because Array isn’t a type, needs to be Array<Something>. As an (impractical) workaround, this compiles: extension Dictionary { subscript(k: Key, default default: Value) -> Value { get { return self[k] ?? `default` } set { self[k] = newValue } } } extension Dictionary where Value: RangeReplaceableCollection { init<S: Sequence>(grouping values: S, by: (S.Iterator.Element) -> Key) where S.Iterator.Element == Value.Iterator.Element { self = [:] for x in values { let k = by(x) self[k, default: Value()].append(x) } } } let s = [10,20,22,30,31] // have to explicitly type the Dictionary as a specific RRC let d: [Int:[Int]] = Dictionary(grouping: s) { $0%10 } print(d)
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution