Swift - Convert Array to Dictionary

后端 未结 7 1513
轻奢々
轻奢々 2021-02-15 12:00

I just want convert an array of Player Names into a dictionary Scoreboard, giving everyone an initial score of 0.

Meaning...

var playerNames =          


        
相关标签:
7条回答
  • 2021-02-15 12:06

    Using reduce(into:_:):

    var playerNames = ["Harry", "Ron", "Hermione"]
    
    let playerScore = playerNames.reduce(into: [:]) { counts, playerNames in
        counts[playerNames, default: 0] += 0 
    }
    
    print(playerScore)
    

    To keep a count of the players names (eg. duplicate names):

    counts[myArray, default: 0] += 1
    

    So for example if Ron had two entries before the game started (score > 0) then you would know.

    Without using reduce(into:_:) method and as an extension:

    var playerNames = ["Harry", "Ron", "Hermione"]
    
    extension Sequence where Self.Iterator.Element: Hashable {
    
    func freq() -> [Self.Iterator.Element: Int] {
        return reduce([:]) {
                ( iter: [Self.Iterator.Element: Int], element) in
                var dict = iter
                dict[element] = 0
                return dict
            }
        }
    }
    
    print(playerNames.freq())
    // ["Harry": 0, "Hermione": 0, "Ron": 0]
    

    keep a count (eg. duplicate names):

    dict[element, default: -1 ] += 1
    
    0 讨论(0)
  • 2021-02-15 12:09

    You can use reduce(into:) as you suspected. You simply need to declare the initial value as [String:Int]() to be an empty Dictionary of the required type, then simply set the value of all keys in playerNames to 0.

    var playerNames = ["Harry", "Ron", "Hermione"]
    var scoreBoard = playerNames.reduce(into: [String:Int](), { currentScores,player in
        currentScores[player] = 0
    })
    
    0 讨论(0)
  • 2021-02-15 12:23

    Here is how you can do that:

    var playerNames = ["Harry", "Ron", "Hermione"]
    
    var dictionary = [String: Int]()
    for player in playerNames {
        dictionary[player] = 0
    }
    
    0 讨论(0)
  • 2021-02-15 12:26

    reduce is definitely one of the more difficult builtin functions to use correctly, but it is what you want here.

    let names = ["Harry", "Ron", "Hermione"]
    let scoreboard: [String: Int] = names.reduce(into: [:], { result, next in
        result[next] = 0
    })
    

    It takes 2 parameters: the initial value (in our case, an empty dictionary [:]), and a closure that updates the result with each element in the array. This closure has 2 parameters, result and next. We want to update result based on the next element. Our closure does this by setting result[next] to 0.

    0 讨论(0)
  • 2021-02-15 12:28

    If the player names are known to be all different then you can do

    let playerNames = ["Harry", "Ron", "Hermione", "Ron"]
    
    var scoreBoard = Dictionary(uniqueKeysWithValues: zip(playerNames,
                                                          repeatElement(0, count: playerNames.count)))
    
    print(scoreBoard) // ["Harry": 0, "Ron": 0, "Hermione": 0]
    

    Here zip is used to create a sequence of player/score pairs, from which the dictionary is created.

    Remark: Originally I had used AnySequence { 0 } to generate the zeros. Using repeatElement() instead was suggested by Alexander and has the advantage that the correct required capacity is passed to the dictionary intializer.

    0 讨论(0)
  • 2021-02-15 12:30

    Here's a quick one liner that I like to use:

    let scoreboard = playerNames.reduce(into: [String: Int]()) { $0[$1] = 0 }
    
    0 讨论(0)
提交回复
热议问题