Сортировать словарь по ключам

128

Я хочу отсортировать словарь в Swift. У меня есть словарь вроде:

"A" => Array[]
"Z" => Array[]
"D" => Array[]

и т. д. я хочу, чтобы это было как

"A" => Array[]
"D" => Array[]
"Z" => Array[]

и т.п.

Я пробовал много решений на SO, но у меня никто не работал. Я использую XCode6 Beta 5, и некоторые из них выдают ошибку компилятора, а некоторые решения дают исключения. Так что всем, кто сможет выложить рабочую копию словаря сортировки.

Алим Ахмад
источник
6
Словарь нельзя отсортировать, это ассоциативный контейнер. Если вам нужен определенный порядок, скопируйте ключи в массив и отсортируйте их. Затем переберите ключи и извлеките их соответствующие значения.
dasblinkenlight
@dasblinkenlight Итак, вы можете мне сказать, как быстро отсортировать массив?
Алим Ахмад
@AleemAhmad Взгляните на этот ответ , у него есть sortedKeysфункция.
dasblinkenlight
@dasblinkenlight Я пробовал это, но он выдает ошибку на [KeyType]
Алим Ахмад

Ответы:

167
let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(<) // ["A", "D", "Z"]

РЕДАКТИРОВАТЬ:

Отсортированный массив из приведенного выше кода содержит только ключи, а значения должны быть извлечены из исходного словаря. Однако 'Dictionary'это также 'CollectionType'пара (ключ, значение), и мы можем использовать глобальную 'sorted'функцию, чтобы получить отсортированный массив, содержащий как ключи, так и значения, например:

let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
println(sortedKeysAndValues) // [(A, [1, 2]), (D, [5, 6]), (Z, [3, 4])]

EDIT2: ежемесячно меняющийся синтаксис Swift в настоящее время предпочитает

let sortedKeys = Array(dictionary.keys).sort(<) // ["A", "D", "Z"]

Глобальный sortedустарел.

Ивица М.
источник
Это дает вам массив ключей. В массиве отсутствуют значения. Думаю, вы можете найти значения в словаре.
StilesCrisis
2
Ты прав. Я только что отредактировал сообщение, чтобы предложить решение для получения массива пар (ключ, значение), отсортированных по ключам. Спасибо за комментарий.
Ivica M.
@IvicaM. Здравствуйте! Я понял, как отсортировать словарь по ключам, но не понимаю, как отсортировать массив элементов в словаре. Пожалуйста, помогите мне. Например, личные контакты var: [(String, [User])] = []
Александр Хитев,
5
Swift 3 = Array (dictionary.keys) .sorted (by: <)
miff
4
Начиная с Swift 4, вы можете писатьlet sortedKeys = dictionary.keys.sorted()
Code Different
113

Swift 2.0

Обновленная версия ответа Ivica M:

let wordDict = [
     "A" : [1, 2],
     "Z" : [3, 4],
     "D" : [5, 6]
]

let sortedDict = wordDict.sort { $0.0 < $1.0 }
print("\(sortedDict)") // 

Swift 3

wordDict.sorted(by: { $0.0 < $1.0 })

Примечание:

Не удивляйтесь, что результирующий тип - это массив, а не словарь. Словари не сортируются ! Результирующий тип данных представляет собой отсортированный массив, как и в ответе @Ivica.

Дэн Болье
источник
26
на самом деле это возвращает массив [(String, [Int])], а не словарь
scord
4
реализованные словари не отсортированы, поэтому в любом случае нет смысла воссоздавать тип данных. В итоге я просто сохранил массив отсортированных ключей.
scord
Я получаю Binary operator > can not be compared to two Any` операнды. Даункастинг тоже не работает
Шон
27

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

let d = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

for (k,v) in Array(d).sorted({$0.0 < $1.0}) {
    println("\(k):\(v)")
}
RKS
источник
отсортировано - это собственный метод или что? он показывает ошибку при внедрении
rikky
@rikkyG Swift 1: sortи sorted. Swift 2: sortстал sortInPlaceи sortedстал sort.
Эрик Айя
14

В Swift 4 вы можете написать умнее:

let d = [ 1 : "hello", 2 : "bye", -1 : "foo" ]
d = [Int : String](uniqueKeysWithValues: d.sorted{ $0.key < $1.key })
Давид Джанесси
источник
3
Спасибо за усилия, но, во-первых, "let" не создает код, поэтому сначала он должен быть "var". Затем после успешной компиляции этот код не работает, он не сортирует словарь. Я получаю тот же результат до и после запуска этого кода. Возможно, мне чего-то не хватает, но, пожалуйста, уточните подробности или измените код. ======= var d = [1: "привет", 2: "пока", -1: "foo"] print (d) - >>> выводит [2: "пока", -1: " foo ", 1:" hello "] d = [Int: String] (uniqueKeysWithValues: d.sorted {$ 0.key <$ 1.key}) print (d) - >>> печатает [2:" пока ", -1 : "foo", 1: "hello"]
Каримихаб
Это невозможно, поскольку, когда вы конвертируете его обратно в словарь, он изменится на неупорядоченную коллекцию, поскольку словари в
Swift
12

Я попробовал все вышеперечисленное, вкратце все, что вам нужно, это

let sorted = dictionary.sorted { $0.key < $1.key }
let keysArraySorted = Array(sorted.map({ $0.key }))
let valuesArraySorted = Array(sorted.map({ $0.value }))

Elsammak
источник
6

Для Swift 4 у меня сработало следующее:

let dicNumArray = ["q":[1,2,3,4,5],"a":[2,3,4,5,5],"s":[123,123,132,43,4],"t":[00,88,66,542,321]]

let sortedDic = dicNumArray.sorted { (aDic, bDic) -> Bool in
    return aDic.key < bDic.key
}
Шив Кумар
источник
5
Это не возвращает словарь, это возвращает массив кортежей
Даниэль Арантес Ловерде,
Словари @DanielArantesLoverde не подлежат сортировке по определению. Лучшее, что вы можете сделать - это массив кортежей.
Джон Монтгомери
1
Я это знаю, но вопрос задаю заказанному, поэтому этот ответ неверный. Вы согласны?
Даниэль Арантес Ловерде
6

Это элегантная альтернатива сортировке самого словаря:

Начиная с Swift 4 и 5

let sortedKeys = myDict.keys.sorted()

for key in sortedKeys {
   // Ordered iteration over the dictionary
   let val = myDict[key]
}
ThunderStruct
источник
6

В Swift 5 для сортировки словаря по КЛЮЧАМ

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.0 < $1.0 })

Для сортировки словаря по ЗНАЧЕНИЯМ

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.1 < $1.1 })
Абдул Карим Хан
источник
4

Для Swift 3 следующая сортировка возвращает отсортированный словарь по ключам:

let unsortedDictionary = ["4": "four", "2": "two", "1": "one", "3": "three"]

let sortedDictionary = unsortedDictionary.sorted(by: { $0.0.key < $0.1.key })

print(sortedDictionary)
// ["1": "one", "2": "two", "3": "three", "4": "four"]
Arijan
источник
10
Это не вернет словарь, это вернет массив
кортежей
Даже не читайте вопрос, прежде чем дать ответ. Вы зря теряете здесь время. Этот вопрос конкретно касается сортировки словаря и получения отсортированного словаря, а не массива. Я не знаю, почему все дают неправильные ответы.
Шивам Похриял
3

"sorted" в iOS 9 и xcode 7.3, swift 2.2 невозможен, измените "sorted" на "sort", например:

let dictionary = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]
let sortedKeysAndValues = Array(dictionary).sort({ $0.0 < $1.0 })
print(sortedKeysAndValues)

//sortedKeysAndValues = ["desert": 2.99, "main course": 10.99, "salad": 5.99]
AmyNguyen
источник
3
Результат sortedKeysAndValues ​​- это не словарь, это массив!
Channel
2
Результат - Arrayof Tuples, а не aDictionary
2

Swift 5

Введите свой словарь, который вы хотите отсортировать в алфавитном порядке по клавишам.

// Sort inputted dictionary with keys alphabetically.
func sortWithKeys(_ dict: [String: Any]) -> [String: Any] {
    let sorted = dict.sorted(by: { $0.key < $1.key })
    var newDict: [String: Any] = [:]
    for sortedDict in sorted {
        newDict[sortedDict.key] = sortedDict.value
    }
    return newDict
}

dict.sorted (by: {$ 0.key <$ 1.key}) сам по себе возвращает кортеж (значение, значение) вместо словаря [значение: значение]. Таким образом, цикл for анализирует кортеж и возвращает его в виде словаря. Таким образом, вы вставите словарь и получите его обратно.

Krekin
источник
2

Swift 4 и 5

Для сортировки строковых ключей:

dictionary.keys.sorted(by: {$0.localizedStandardCompare($1) == .orderedAscending})

Пример:

var dict : [String : Any] = ["10" : Any, "2" : Any, "20" : Any, "1" : Any]

dictionary.keys.sorted() 

["1" : Any, "10" : Any, "2" : Any, "20" : Any]

dictionary.keys.sorted(by: {$0.localizedStandardCompare($1) == .orderedAscending})

["1" : Any, "2" : Any, "10" : Any, "20" : Any]

Xav Mac
источник
1

Для Swift 3 у меня сработало следующее, а синтаксис Swift 2 не сработал:

// menu is a dictionary in this example

var menu = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]

let sortedDict = menu.sorted(by: <)

// without "by:" it does not work in Swift 3
Joeri
источник
Этот ответ довольно неполный. Что есть sortedDict? Что есть menu? Этот код также кажется недействительным.
random_user_name
Теперь кое-что более серьезное: в словаре нет порядка . С вашим кодом вы получаете массив кортежей, а не отсортированный словарь, как уже было сказано в некоторых ответах и ​​комментариях.
Эрик Ая,
тема: сортировать словарь по ключам, в этой теме отвечаю. И это конкретное замечание, касающееся только изменения синтаксиса в Swift 3, оно не отрицает ничего из того, что было написано ранее.
Joeri
«Этот ответ довольно неполный. Что такое sortedDict? Что такое меню? Этот код, похоже, тоже недействителен. - cale_b» Ответ был отредактирован, единственное, чего не хватало, это объявление для dictionaty - menu. Я думал, что это ясно, речь идет только об изменении синтаксиса в Swift 3, как указано. Код действительно работает в Swift 3.
Joeri
какие-нибудь предложения для быстрой 4 плз?
famfamfam
1

Swift 3 отсортирован (по: <)

let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(by:<) // ["A", "D", "Z"]
Shadros
источник