2016-12-27 6 views
0

Ссылаясь на: Swift Standard Library> Словарь>map(_:)Есть ли подход к карте словарных ключей/значений одновременно в Swift?

возвраты Массив, содержащих результаты отображения данного закрытия над элементами последовательности, в.

Как уже упоминалось, мы можем сделать отображение в словарях, но выход будет массив, а не «отображается» словарь.

Честно говоря, я не уверен, что, если говорить «картирование весь словарь» является законным, но то, что я имею в виду следующее:

Считают, что мы имеем:

let myDict = ["1": "one","2": "tow","3": "three"] 

и мы хотим чтобы отобразить все это! (оба ключа и значения). Вывод должен быть:

let mappedDict = ["03": "THREE", "02": "TOW", "01": "ONE"] 

Предположим, что цель отображения является добавление «0» в качестве первого символа для всех ключей, и пусть все значения, чтобы быть в верхнем регистре.

Чтобы сделать его более читаемым, я отправил решение (то, что я пробовал) в качестве ответа, вместо того, чтобы упоминать его в вопросе о себе; Я думаю, что мой ответ не такой элегантный (или, по крайней мере, как я чувствую его запах кода), я отобразил ключи, значения и объединил их в словаре, каждый шаг был достигнут независимо.

Итак, что я спрашиваю о том:

Есть ли способ, чтобы сделать эту работу непосредственно в один шаг? Нечто похожее на:

Этот фрагмент кода является демонстрация того, что я спрашиваю о, код не будет работать нормально

let myDict = ["1": "one","2": "tow","3": "three"] 
let mappedDict = myDict.map { key, value in 
    "0" + key 
    value.uppercased() 
} 

Спасибо заранее.

ответ

0

Вы можете добиться этого, выполнив следующие действия:

let myDict = ["1": "one","2": "tow","3": "three"] 

let mappedKeys = myDict.map { "0" + $0.key } // ["02", "01", "03"] 
let mappedValues = myDict.map { $0.value.uppercased() } // ["TOW", "ONE", "THREE"] 

var mappedDict = [String: String]() 

let zippedArray = Array((zip(mappedKeys, mappedValues))) 

for element in zippedArray { 
    mappedDict[element.0] = element.1 
} 

print(mappedDict) // ["03": "THREE", "02": "TOW", "01": "ONE"] 

Чтобы быть более ясным, выше фрагмент кода, выполнив следующие действия:

  • Отображение ключей словаря.
  • Сопоставление значений словаря.
  • Создайте новый пустой словарь mappedDict, чтобы добавить к нему.
  • Объединение отображаемых ключей/значений в zippedArray (с использованием zip).
  • Заполнение mappedDict через for-loop.
+0

Почему вы не просто изменить ключи и добавить значения непосредственно в 'mappedDict' вместо так что вы можете пропустить создание' mappedKeys', '' mappedValues' и zippedArray'. – Eendje

+3

Нет необходимости конвертировать zipped-последовательности в 'Array', вы можете перебирать их напрямую. Также почему бы просто не перебирать словарь напрямую и применять преобразования к ключам и значениям в цикле? (например, 'for (key, value) в myDict {mappedDict [" 0 "+ key] = value.uppercased()}')? – Hamish

+0

@Eendje Я отделяю их только для того, чтобы сделать его более читабельным ... кстати, вы думаете, что весь ответ - хорошее решение? –

0

Как насчет этого?

let myDict = ["1": "one","2": "tow","3": "three"] 
let mappedDict = myDict.reduce([:]) { (result, pair) -> [String: String] in 
    var result = result 
    result["0" + pair.key] = pair.value.uppercased() 
    return result 
} 
+2

Обратите внимание, что 'reduce' будет создавать промежуточный словарь для каждой итерации, заставляя его работать в квадратичном, а не в линейном времени. В этом случае простой цикл 'for' является более чистым, короче и * будет * работать в линейном режиме. – Hamish

+0

@ Хамиш как выступление, не могли бы вы описать его простым способом, в чем разница? –

+1

@AhmadF Разница в том, что цикл 'for' [такой, как предлагается в моем другом комментарии] (http://stackoverflow.com/questions/41342582/is-there-approach-to-map-dictionary-keys-values- одновременный-в-swift # comment69887453_41342591) способен напрямую мутировать результирующий словарь (из-за оптимизации COW, где имеется только одна ссылка на буфер). С другой стороны, 'reduce' будет * копировать * результирующий словарь на каждой итерации, что означает, что результирующий словарь будет итерирован для каждой итерации, которая' reduce' делает, поэтому работает медленнее, чем цикл 'for'. – Hamish