Сортировка словаря в Swift
Я знаю, что эта тема уже обсуждалась, но я не могу решить, глядя на другие ответы, поэтому заранее извините за мое созревание!
мне нужно отсортировать этот словарь по ключам
codeValueDict = ["us": "$", "it": "€", "fr": "€"]
поэтому мне нужен такой словарь
sortedDict = ["fr": "€", "it": "€", "us": "$"]
но я не могу этого сделать.
Я пробовал это
let sortedKeysAndValues = sorted(dictionary) { .0 < .0 }
но после того, как мне нужно создать два массива из этого словаря (ключи и значения) и, используя это решение
codesArray = sortedKeysAndValues.keys.array
дать мне ошибка ' [(String, String)]' не имеет члена с именем 'keys' потому что это решение не совсем словарь.
так я попробовал другое решение:
let prova = codiceNomeDict as NSDictionary
for (k,v) in (Array(codiceNomeDict).sorted {.1 < .1}) {
let value = "["(k)": "(v)"]"
println(value)
}
, которая работает хорошо, но тогда я не знаю, как создать новый словарь стоимостьюs.
что самое лучшее решение? Как сделать это работает?
6 ответов
выход .0 < .0}) print(sortedArray) let keys = sortedArray.map {return .0 } print(keys) let values = sortedArray.map {return .1 } print(values)
словари не упорядочены. Если вы хотите перечислить их по порядку, вы можете сделать это, используя решение @HoaParis (что является моим предпочтением), а также
for (k,v) in sorted(codiceNomeDict, {.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 }
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
в целом.
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
}
}
вы не можете сортировать словарь таким простым способом. Я думаю, что словарь использует какую-то структуру данных дерева. Но после сортировки вы получаете массив кортежей. Таким образом, вы можете получить ключи таким образом:
let codeValueDict = ["us": "$", "it": "€", "fr": "€"]
let sortedKeysAndValues = sorted(codeValueDict) { .0 < .0 }
let keys = sortedKeysAndValues.map {.0 }
let values = sortedKeysAndValues.map {.1 }
сортировка ключей по значению словаря на самом деле проще, чем кажется на первый:
let yourDict = ["One": "X", "Two": "B", "Three": "Z", "Four": "A"]
let sortedKeys = yourDict.keys.sort({ (firstKey, secondKey) -> Bool in
return yourDict[firstKey] < yourDict[secondKey]
})
и это все! Больше ничего нет.
сортировка ключей без учета регистра в Swift 2
вот функция, которая возвращает регистр отсортированный массив ключей (или любые строковые значения).
пожалуйста, имейте в виду, что структура данных словаря Swift не может быть сохранена отсортированными по ключам в памяти. Так что да, вы можете сортировать его по ключам, но если вы печатаете его, например, то порядок ключей снова случайный.
/// 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))