> On Feb 19, 2017, at 6:13 PM, Ben Cohen via swift-evolution > <swift-evolution@swift.org> wrote: > >> On Feb 19, 2017, at 11:22 AM, Ole Begemann <o...@oleb.net >> <mailto: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 { >> ... >> } >> } >> }
I don't totally have my head around this, but won't a Dictionary initializer like this require parameterized extensions as described in the generics manifesto? https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions Something like this: extension Dictionary<T> where Value == [T] { init<S: Sequence>(_ values: S, groupedBy: (S.Iterator.Element) -> Key) where S.Iterator.Element == T { ... } } For what it's worth, I had been expecting that we'd add this as a method on Sequence, a la joined(by:), not an initializer. extension Sequence { func grouped<Key: Hashable>(by grouping: (Iterator.Element) -> Key) -> [Key: [Iterator.Element]] { ... } } let d = (1...10).grouped(by: { $0 % 3 }) // [2: [2, 5, 8], 0: [3, 6, 9], 1: [1, 4, 7, 10]] Nate > 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 > <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 <mailto:swift-evolution@swift.org> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution