Сортировка словаря в Swift
Я знаю, что эта тема уже обсуждалась, но я не могу решить другие ответы, поэтому извините заранее за мой ритуал!
Мне нужно отсортировать этот словарь по клавишам
codeValueDict = ["us": "$", "it": "€", "fr": "€"]
поэтому мне нужен такой словарь
sortedDict = ["fr": "€", "it": "€", "us": "$"]
но я не могу этого сделать.
Я пробовал это
let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
но после того, как мне нужно создать два массива из этого словаря (ключи и значения) и, используя это решение
codesArray = sortedKeysAndValues.keys.array
дайте мне ошибку '[(String, String)]' не имеет члена с именем 'keys', потому что это решение не возвращает точно словарь.
Итак, я попробовал другое решение:
let prova = codiceNomeDict as NSDictionary
for (k,v) in (Array(codiceNomeDict).sorted {$0.1 < $1.1}) {
let value = "[\"\(k)\": \"\(v)\"]"
println(value)
}
Что работает хорошо, но тогда я не знаю, как создать новый словарь значений.
Какое лучшее решение? Как заставить его работать?
Ответы
Ответ 1
Вывод функции sorted
выше - Массив. Таким образом, вы не можете получить ключи и значения, например Словарь. Но вы можете использовать функцию map
для извлечения этих отсортированных ключей и значений
Возвращает массив, содержащий отсортированные элементы source
{согласно}. Алгоритм сортировки нестабилен (можно изменить относительный порядок элементы, для которых isOrderedBefore не устанавливает порядок).
let codeValueDict = ["us": "$", "it": "€", "fr": "€"]
let sortedArray = sorted(codeValueDict, {$0.0 < $1.0})
print(sortedArray)
let keys = sortedArray.map {return $0.0 }
print(keys)
let values = sortedArray.map {return $0.1 }
print(values)
Ответ 2
Словари не упорядочены. Если вы хотите перечислить их по порядку, вы можете сделать это с помощью решения @HoaParis (что является моим предпочтением), а также
for (k,v) in sorted(codiceNomeDict, {$0.1 < $1.1}) { ... }
который немного лучше, чем то, что вы делали раньше, потому что оно не создает временный массив.
Но если вы действительно хотите "коллекцию, которая отображает одно значение в другое и упорядочивается по его ключу", тогда вам нужно создать для этого другую структуру данных. Так что сделайте это. Это хороший опыт обучения.
Эта версия просто реализует SequenceType
и предоставляет индекс get/set, который больше всего вам нужен. Полагаю, что полная CollectionType
- это немного боль, о которой я думаю, поскольку startIndex
и endIndex
hae - O (1). Возможное; просто больше, чем я хочу сделать сегодня утром.
Обратите внимание на основное дополнение Key: Comparable
. Поэтому Dictionary
нельзя упорядочить. Там нет обещания, что вы можете сортировать свои ключи. Добавив это требование, мы можем.
struct SortedDictionary<Key: Hashable, Value where Key: Comparable>: SequenceType {
private var dict: Dictionary<Key, Value>
init(_ dict: Dictionary<Key, Value>) {
self.dict = dict
}
func generate() -> GeneratorOf<(Key, Value)> {
let values = Array(zip(self.dict.keys, self.dict.values))
.sorted {$0.0 < $1.0 }
return GeneratorOf(values.generate())
}
subscript(key: Key) -> Value? {
get { return self.dict[key] }
set(value) { self.dict[key] = value }
}
}
var codeValueDict = ["us": "$", "it": "€", "fr": "€"]
var sortedDict = SortedDictionary(codeValueDict)
for (k, v) in sortedDict {
println("\(k) => \(v)")
}
sortedDict["us"]
sortedDict["ab"] = "!"
sortedDict
Зачем вам беспокоиться с SortedDictionary
, когда у вас уже есть sorted()
? Ну, обычно я бы не стал. Но он предлагает возможности для абстракции. Вы можете контролировать порядок сортировки при создании объекта, а не при перечислении объектов. Вы можете кэшировать порядок сортировки (хотя я подозреваю, что в большинстве случаев это будет больно, а не помощь).
Но я рекомендую просто использовать sorted
вообще.
Ответ 3
Swift не включает отсортированный тип словаря, и словари не могут быть отсортированы. Вы можете добавить расширение, предлагающее сортировку [(Key, Value)]
, выполнив следующее:
extension Dictionary {
func sort(isOrderedBefore: (Key, Key) -> Bool) -> [(Key, Value)] {
var result: [(Key, Value)] = []
let sortedKeys = keys.array.sorted(isOrderedBefore)
for key in sortedKeys {
result.append(key, self[key]!)
}
return result
}
}
Ответ 4
Вы не можете сортировать словарь таким простым способом. Я думаю, что словарь использует какую-то структуру данных дерева. Но после сортировки вы получаете массив кортежей. Таким образом, вы можете получить ключи таким образом:
let codeValueDict = ["us": "$", "it": "€", "fr": "€"]
let sortedKeysAndValues = sorted(codeValueDict) { $0.0 < $1.0 }
let keys = sortedKeysAndValues.map {$0.0 }
let values = sortedKeysAndValues.map {$0.1 }
Ответ 5
Сортировка ваших ключей по значению словаря на самом деле проще, чем сначала:
let yourDict = ["One": "X", "Two": "B", "Three": "Z", "Four": "A"]
let sortedKeys = yourDict.keys.sort({ (firstKey, secondKey) -> Bool in
return yourDict[firstKey] < yourDict[secondKey]
})
И это! Там действительно ничего более.
Ответ 6
Сортировка ключей без учета регистра в Swift 2
Вот функция, которая возвращает нечувствительный к регистру отсортированный массив ключей (или любые значения String).
Пожалуйста, имейте в виду, что структуру данных словаря Swifts нельзя хранить, отсортированную по ключам в памяти. Так что да, вы можете отсортировать его по клавишам, но если вы напечатаете его, например, тогда порядок клавиш снова будет случайным.
/// returns an array of values sorted by values case-insensitive
func sortCaseInsensitive(values:[String]) -> [String]{
let sortedValues = values.sort({ (value1, value2) -> Bool in
if (value1.lowercaseString < value2.lowercaseString) {
return true
} else {
return false
}
})
return sortedValues
}
Вызов с
let dict = ["world": "Hello!", "foo": "bar", "zYeah": "a", "akey": "xval"]
let sortedKeys = sortCaseInsensitive(Array(dict.keys))