Ordenar diccionario por claves


128

Quiero ordenar un diccionario en Swift. Tengo un diccionario como:

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

etc. Quiero que sea como

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

etc.

He intentado muchas soluciones en SO pero nadie trabajó para mí. Estoy usando XCode6 Beta 5 y en él algunos están dando error de compilación y algunas soluciones están dando excepciones. Entonces, cualquiera que pueda publicar la copia de trabajo de la clasificación del diccionario.



66
No se puede ordenar un diccionario, es un contenedor asociativo. Si necesita un pedido en particular, copie las claves en una matriz y ordénelas. Luego, repita las teclas y extraiga sus valores correspondientes.
dasblinkenlight

@dasblinkenlight Entonces, ¿puedes decirme cómo ordenar una matriz de manera rápida?
Aleem Ahmad

@AleemAhmad Echa un vistazo a esta respuesta , tiene sortedKeysfunción.
dasblinkenlight

@dasblinkenlight He intentado esto pero está dando error en [KeyType]
Aleem Ahmad

Respuestas:


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

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

EDITAR:

La matriz ordenada del código anterior contiene solo claves, mientras que los valores deben recuperarse del diccionario original. Sin embargo, 'Dictionary'también es un 'CollectionType'par de (clave, valor) y podemos usar la 'sorted'función global para obtener una matriz ordenada que contenga tanto claves como valores, de esta manera:

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

EDIT2: la sintaxis Swift cambiante mensual prefiere actualmente

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

Lo global sortedestá en desuso.


Esto le brinda una variedad de claves. La matriz carece de los valores. Podrías buscar los valores del diccionario, supongo.
StilesCrisis

2
Tienes razón. Acabo de editar la publicación para proporcionar una solución para obtener una matriz de pares (clave, valor) ordenados por claves. Gracias por el comentario.
Ivica M.

@IvicaM. ¡Hola! Comprendí cómo puedo ordenar el diccionario por teclas, pero no entiendo cómo puedo ordenar una matriz de elementos en el diccionario. Por favor, ayúdame. Por ejemplo, contactos var privados: [(String, [User])] = []
Alexander Khitev

55
Swift 3 = Array (dictionary.keys) .sorted (by: <)
miff

44
A partir de Swift 4, puede escribirlet sortedKeys = dictionary.keys.sorted()
Code Different

113

Swift 2.0

Versión actualizada de la respuesta de 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 })

Aviso:

No se sorprenda de que el tipo resultante sea una matriz en lugar de un diccionario. ¡Los diccionarios no se pueden ordenar ! El tipo de datos resultante es una matriz ordenada, al igual que en la respuesta de @ Ivica.


26
esto en realidad devuelve una matriz de [(String, [Int])] no un diccionario
scord

44
los diccionarios realizados no están clasificados, por lo que no tiene mucho sentido recrear el tipo de datos de todos modos. Terminé simplemente guardando una serie de claves ordenadas.
scord

Obtengo Binary operator > can not be compared to two cualquier operandos. Downcasting tampoco funciona
Sean

27

Si desea iterar sobre las claves y los valores en un orden ordenado por clave, este formulario es bastante sucinto

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)")
}

ordenado es Método personalizado o ¿Qué? muestra error al implementar
rikky

@rikkyG Swift 1: sorty sorted. Swift 2: se sortha convertido sortInPlacey se sortedha convertido sort.
Eric Aya

14

En swift 4 puedes escribirlo de manera más inteligente:

let d = [ 1 : "hello", 2 : "bye", -1 : "foo" ]
d = [Int : String](uniqueKeysWithValues: d.sorted{ $0.key < $1.key })

3
Gracias por el esfuerzo, pero antes que nada, "let" no crea el código, por lo que primero debe ser "var". Luego, después de que la compilación tenga éxito, este código no funciona, no clasifica el diccionario, obtengo el mismo resultado antes y después de ejecutar este código. Tal vez me estoy perdiendo algo, pero explique más o cambie el código. ======= var d = [1: "hola", 2: "adiós", -1: "foo"] imprimir (d) - >>> imprime [2: "adiós", -1: " foo ", 1:" hola "] d = [Int: String] (uniqueKeysWithValues: d.sorted {$ 0.key <$ 1.key}) print (d) - >>> imprime [2:" bye ", -1 : "foo", 1: "hola"]
KarimIhab

No es posible ya que cuando lo convierte de nuevo al diccionario, cambiará a la colección no ordenada ya que los diccionarios en
Swift

12

Intenté todo lo anterior, en pocas palabras todo lo que necesitas es

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


6

Para Swift 4, lo siguiente me ha funcionado:

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
}

55
Esto no devuelve un Diccionario, esto devolverá una serie de tuplas
Daniel Arantes Loverde

@DanielArantesLoverde Los diccionarios no se pueden ordenar por definición. Una serie de tuplas es lo mejor que puedes hacer.
John Montgomery

1
Lo sé, pero la pregunta pide un pedido, por lo que esta respuesta no es correcta. ¿Estás de acuerdo?
Daniel Arantes Loverde

6

Esta es una alternativa elegante para ordenar el diccionario en sí:

A partir de Swift 4 y 5

let sortedKeys = myDict.keys.sorted()

for key in sortedKeys {
   // Ordered iteration over the dictionary
   let val = myDict[key]
}

6

En Swift 5 , para ordenar el Diccionario por CLAVES

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

Para ordenar el Diccionario por VALORES

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.1 < $1.1 })

4

Para Swift 3, el siguiente tipo retorna el diccionario ordenado por claves:

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"]

10
Esto no devolverá un diccionario, devolverá una serie de
Tuplas

Ni siquiera leas la pregunta antes de poner tu respuesta. Estás perdiendo el tiempo de muchas personas aquí. Esta pregunta trata específicamente de ordenar un diccionario y obtener un diccionario ordenado, no una matriz. No sé por qué todos están dando respuestas incorrectas.
Shivam Pokhriyal

3

"ordenado" en iOS 9 y xcode 7.3, swift 2.2 es imposible, cambie "ordenado" a "ordenar", así:

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]

3
El resultado de sortedKeysAndValues ​​no es un diccionario, ¡es una matriz!
Canal

2
El resultado es una Arrayde las Tuples, no unDictionary

2

Swift 5

Ingrese el diccionario que desea ordenar alfabéticamente por teclas.

// 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 (por: {$ 0.key <$ 1.key}) por sí mismo devuelve una tupla (valor, valor) en lugar de un diccionario [valor: valor]. Por lo tanto, el bucle for analiza la tupla para que regrese como un diccionario. De esa manera, pones un diccionario y recuperas un diccionario.


2

Swift 4 y 5

Para la clasificación de claves de cadena:

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

Ejemplo:

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]


1

Para Swift 3, lo siguiente me funcionó y la sintaxis de Swift 2 no funcionó:

// 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

Esta respuesta es bastante incompleta. ¿Qué es sortedDict? ¿Qué es menu? Este código tampoco parece ser válido.
random_user_name

Algo más serio ahora: un diccionario no tiene orden . Lo que obtienes con tu código es una serie de tuplas, no un diccionario ordenado, como ya se dijo en algunas respuestas y comentarios.
Eric Aya

el tema es: ordenar el diccionario por teclas, estoy respondiendo a este tema. Y es un comentario específico sobre solo un cambio de sintaxis en Swift 3, no niega nada de lo que se ha escrito antes.
Joeri

"Esta respuesta es bastante incompleta. ¿Qué está ordenado? ¿Qué es el menú? Este código tampoco parece ser válido. - cale_b" La respuesta fue editada, lo único que faltaba era una declaración para un menú de dicción. Pensé que estaba claro, esto solo se trata de un cambio de sintaxis en Swift 3 como se indica. El código funciona en Swift 3.
Joeri

alguna sugerencia para swift 4 por favor?
famfamfam

1

Swift 3 está ordenado (por: <)

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

let sortedKeys = Array(dictionary.keys).sorted(by:<) // ["A", "D", "Z"]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.