[swift-evolution] map-like operation that returns a dictionary

Brent Royal-Gordon brent at architechies.com
Sun Jan 10 17:19:12 CST 2016


> If there was an initialiser for Dictionary which took an Array or EnumerateSequence, that might be useful. I'm not sure how I'd attempt to write such an initialiser though.

Well, we can begin with a simple "initialize from key-value tuple sequence" initializer:

	init?<Sequence: SequenceType where Sequence.Generator.Element == Element>(_ seq: Sequence) {
		self.init()
		for (key, value) in seq {
			let oldValue = updateValue(value, forKey: key)
			
			// Did this key already have a value?
			if oldValue != nil {
				return nil
			}
		}
	}

Now you can say things like:

	Dictionary(array.map { ($0.identifier, $0) })

If you want to special-case "invert a collection into an element-to-index dictionary", you could add something like this:

	init?<Collection: CollectionType where Collection.Generator.Element == Key, Collection.Index == Value>(ofIndices collection: Collection) {
		self.init(zip(collection, collection.indices))
	}

Unfortunately, this specific implementation emits a bizarre error on the `collection.indices` expression, complaining that "value of type 'Collection' has no member 'IntegerLiteralType'"; I must be doing something wrong. But a properly working version of that would allow you to say:

	Dictionary(ofIndices: array)

These two initializers might be useful enough to be worth including in the standard library.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list