<div dir="ltr">Hello everyone,<div><br></div><div>I have added a very simple, but powerful method into a Dictionary extension on multiple projects in the last weeks, so I&#39;d like to bring up the idea of adding it into the standard library, in case other people can see its benefits as well.</div><div><br></div><div>Currently, Dictionary conforms to Collection with its Element being the tuple of Key and Value. Thus transforming the Dictionary with regular map results in [T], whereas I&#39;d find it more useful to also have a method which results in [Key:T].</div><div><br></div><div>Let me present an example of where this makes sense.</div><div><br></div><div>I recently used the GitHub API to crawl some information about repositories. I started with just names (e.g. &quot;/apple/swift&quot;, &quot;/apple/llvm&quot;) and fetched a JSON response for each of the repos, each returning a dictionary, which got saved into one large dictionary as the end of the full operation, keyed by its name, so the structure was something like</div><div><br></div><div>{</div><div>  &quot;/apple/swift&quot;: { &quot;url&quot;:..., &quot;size&quot;:...., &quot;homepage&quot;:... },</div><div>  &quot;/apple/llvm&quot;: { &quot;url&quot;:..., &quot;size&quot;:...., &quot;homepage&quot;:... },<br></div><div>  ...</div><div>}</div><div><br></div><div>To perform analysis, I just needed a dictionary mapping the name of the repository to its size, freeing me to discard the rest of the results.</div><div>This is where things get interesting, because you can&#39;t keep this action nicely functional anymore. I had to do the following:</div><div><br></div><div>let repos: [String: JSON] = ...</div><div>var sizes: [String: Int] = [:]</div><div>for (key, value) in repos {</div><div>  sizes[key] = value[&quot;size&quot;].int</div><div>}</div><div>// use sizes...</div><div><br></div><div>Which isn&#39;t a huge amount of work, but it creates unnecessary mutable state in your transformation pipeline (and your current scope). And I had to write it enough times to justify bringing it up on this list.</div><div><br></div><div>I suggest we add the following method to Dictionary:</div><div><br></div><div>extension Dictionary {</div><div>      public func mapValues&lt;T&gt;(_ transform: @noescape (Value) throws -&gt; T) rethrows -&gt; [Key: T] {</div><div>        var transformed: [Key: T] = [:]</div><div>        for (key, value) in self {</div><div>            transformed[key] = try transform(value)</div><div>        }</div><div>        return transformed</div><div>    }</div><div>}</div><div><br></div><div>It is modeled after Collection&#39;s `map` function, with the difference that </div><div> a) only values are transformed, instead of the Key,Value tuple and </div><div> b) the returned structure is a transformed Dictionary [Key:T], instead of [T]</div><div><br></div><div>This now allows a much nicer workflow:</div><div><br></div><div><div>let repos: [String: JSON] = ...</div><div>var sizes = repos.mapValues { $0[&quot;size&quot;].int }</div><div>// use sizes...</div><div><br></div><div>and even multi-step transformations on Dictionaries, previously only possible on Arrays, e.g. </div><div>var descriptionTextLengths = repos.mapValues { $0[&quot;description&quot;].string }.mapValues { $0.characters.count }</div><div><br></div><div>You get the idea.</div><div><br></div><div>What do you think? I welcome all feedback, I&#39;d like to see if people would support it before I write a proper proposal.</div><div><br></div><div>Thanks! :)</div><div>Honza Dvorsky</div><div><br></div></div></div>