Swift - конвертировать массив в словарь - PullRequest
0 голосов
/ 12 июня 2018

Я просто хочу преобразовать массив имен игроков в табло словаря, давая каждому начальное значение 0.

Значение ...

var playerNames = ["Harry", "Ron", "Hermione"]

становится ...

var scoreBoard: [String:Int] = [ "Ron":0, "Harry":0, "Hermione":0 ]

Я впервые задаю вопрос, но я полностью застрял на том, что мне кажется таким простым, и на все вопросы и ответынайдены в некотором роде.Я пытался использовать снижение по-разному, но всегда заканчивался коротким.Заранее спасибо!

Ответы [ 6 ]

0 голосов
/ 12 июня 2018

Вот один быстрый лайнер, который мне нравится использовать:

let scoreboard = playerNames.reduce(into: [String: Int]()) { $0[$1] = 0 }
0 голосов
/ 12 июня 2018

Использование reduce(into:_:):

var playerNames = ["Harry", "Ron", "Hermione"]

let playerScore = playerNames.reduce(into: [:]) { counts, playerNames in
    counts[playerNames, default: 0] += 0 
}

print(playerScore)

Для подсчета имен игроков (например, дубликаты имен):

counts[myArray, default: 0] += 1

Так, например, если бы у Рона было две записи до начала игры (счет> 0), то вы бы знали.

Без использования метода reduce(into:_:) и в качестве расширения:

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]

вести подсчет (например, повторяющиеся имена):

dict[element, default: -1 ] += 1
0 голосов
/ 12 июня 2018

Если известно, что имена игроков различны, вы можете сделать

let playerNames = ["Harry", "Ron", "Hermione", "Ron"]

var scoreBoard = Dictionary(uniqueKeysWithValues: zip(playerNames, AnyIterator { 0 }))

print(scoreBoard) // ["Harry": 0, "Ron": 0, "Hermione": 0]

Здесь zip используется для создания последовательности пар игрок / счет, из которых создается словарь.

0 голосов
/ 12 июня 2018

reduce определенно является одной из наиболее сложных встроенных функций для правильного использования, но это то, что вам нужно здесь.

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

Требуется 2 параметра: начальное значение (в нашем случае пустой словарь [:]) и замыкание, которое обновляет результат с каждым элементом в массиве.Это закрытие имеет 2 параметра, result и next.Мы хотим обновить result на основе элемента next.Наше закрытие делает это, устанавливая result[next] в 0.

0 голосов
/ 12 июня 2018

Вы можете использовать reduce(into:), как вы и предполагали.Вам просто нужно объявить начальное значение как [String:Int]() как пустое Dictionary требуемого типа, а затем просто установить значение всех ключей в playerNames равным 0.

var playerNames = ["Harry", "Ron", "Hermione"]
var scoreBoard = playerNames.reduce(into: [String:Int](), { currentScores,player in
    currentScores[player] = 0
})
0 голосов
/ 12 июня 2018

Вот как вы можете это сделать:

var playerNames = ["Harry", "Ron", "Hermione"]

var dictionary = [String: Int]()
for player in playerNames {
    dictionary[player] = 0
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...