Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invert keys for values in Swift dictionary, collecting duplicate values

I have the following dictionary:

let dict = ["key1": "v1", "key2": "v1", "key3": "v2"]

I want to swap the values for keys so that the result to be:

result = ["v1": ["key1", "key2"], "v2": ["key3"]]

How can I do this without using for loops (i.e. in a functional way)?

like image 618
Teodor Ciuraru Avatar asked Mar 03 '18 19:03

Teodor Ciuraru


2 Answers

In Swift 4, Dictionary has the init(_:uniquingKeysWith:) initializer that should serve well here.

let d = [1 : "one", 2 : "two", 3 : "three", 30: "three"]
let e = Dictionary(d.map({ ($1, [$0]) }), uniquingKeysWith: {
    (old, new) in old + new
})

If you did not have duplicate values in the original dict that needed to be combined, this would be even simpler (using another new initializer):

let d = [1 : "one", 2 : "two", 3 : "three"]
let e = Dictionary(uniqueKeysWithValues: d.map({ ($1, $0) }))
like image 52
jscs Avatar answered Sep 24 '22 15:09

jscs


You can use grouping initializer in Swift 4:

let dict = ["key1": "v1", "key2": "v1", "key3": "v2"]
let result = Dictionary(grouping: dict.keys.sorted(), by: { dict[$0]! })

Two notes:

  1. You can remove .sorted() if the order of keys in resulting arrays is not important.
  2. Force unwrap is safe in this case because we're getting an existing dictionary key as the $0 parameter
like image 39
Dan Karbayev Avatar answered Sep 22 '22 15:09

Dan Karbayev