Map array of objects to Dictionary in Swift

前端 未结 9 502
半阙折子戏
半阙折子戏 2021-01-30 00:32

I have an array of Person\'s objects:

class Person {
   let name:String
   let position:Int
}

and the array is:

         


        
9条回答
  •  礼貌的吻别
    2021-01-30 01:23

    Since Swift 4 you can do this very easily. There are two new initializers that build a dictionary from a sequence of tuples (pairs of key and value). If the keys are guaranteed to be unique, you can do the following:

    let persons = [Person(name: "Franz", position: 1),
                   Person(name: "Heinz", position: 2),
                   Person(name: "Hans", position: 3)]
    
    Dictionary(uniqueKeysWithValues: persons.map { ($0.position, $0.name) })
    

    => [1: "Franz", 2: "Heinz", 3: "Hans"]

    This will fail with a runtime error if any key is duplicated. In that case you can use this version:

    let persons = [Person(name: "Franz", position: 1),
                   Person(name: "Heinz", position: 2),
                   Person(name: "Hans", position: 1)]
    
    Dictionary(persons.map { ($0.position, $0.name) }) { _, last in last }
    

    => [1: "Hans", 2: "Heinz"]

    This behaves as your for loop. If you don't want to "overwrite" values and stick to the first mapping, you can use this:

    Dictionary(persons.map { ($0.position, $0.name) }) { first, _ in first }
    

    => [1: "Franz", 2: "Heinz"]

    Swift 4.2 adds a third initializer that groups sequence elements into a dictionary. Dictionary keys are derived by a closure. Elements with the same key are put into an array in the same order as in the sequence. This allows you to achieve similar results as above. For example:

    Dictionary(grouping: persons, by: { $0.position }).mapValues { $0.last! }
    

    => [1: Person(name: "Hans", position: 1), 2: Person(name: "Heinz", position: 2)]

    Dictionary(grouping: persons, by: { $0.position }).mapValues { $0.first! }
    

    => [1: Person(name: "Franz", position: 1), 2: Person(name: "Heinz", position: 2)]

提交回复
热议问题