Iterar a través de un Diccionario en Swift


Estoy un poco confundido sobre la respuesta que Xcode me está dando a este experimento en la Guía del Lenguaje de Programación Swift:

// Use a for-in to iterate through a dictionary (experiment)

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

Entiendo que a medida que el diccionario está siendo transversal, el número más grande se establece en la variable, largest. Sin embargo, estoy confundido en cuanto a por qué Xcode está diciendo que largest se está estableciendo 5 veces, o 1 vez, o 3 veces, dependiendo de cada prueba.

Al mirar a través del código, veo que se debe establecer 6 veces solo en" Prime " (2, 3, 5, 7, 11, 13). Entonces debe omitir cualquier número en "Fibonacci", ya que todos son menores que el más grande, que actualmente se establece en 13 desde"Prime". Luego, se debe establecer en 16, y finalmente 25 en "Cuadrado", produciendo un total de 8 veces.

¿Me estoy perdiendo algo completamente obvio?

Author: Nick Kohrn, 2014-06-09

4 answers

Los diccionarios en Swift (y otros idiomas) no están ordenados. Cuando se itera a través del diccionario, no hay garantía de que el orden coincidirá con el orden de inicialización. En este ejemplo, Swift procesa la tecla" Cuadrado " antes que los demás. Puede ver esto agregando una instrucción print al bucle. 25 es el 5to elemento del Cuadrado tan más grande sería fijado 5 veces para los 5 elementos en Cuadrado y entonces permanecería en 25.

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    println("kind: \(kind)")
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

Esto imprime:

kind: Square
kind: Prime
kind: Fibonacci
 280
Author: Dash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-04 02:25:53
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }

El Resultado sería

("FirstName", " Maninder") ("Apellido", " Singh") ("Dirección", "Chandigarh")

 9
Author: Maninderjit Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 07:26:55

Aquí hay una alternativa para ese experimento (Swift 3.0). Esto te dice exactamente qué tipo de número era el más grande.

let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]

var largest = 0
var whichKind: String? = nil

for (kind, numbers) in interestingNumbers {
    for number in numbers {
    if number > largest {
        whichKind = kind
        largest = number
    }
  }
}

print(whichKind)
print(largest)

OUTPUT:
Optional("Square")
25
 8
Author: jabbyApps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-12 17:19:07

Los arrays son colecciones ordenadas, pero los diccionarios y los conjuntos son colecciones desordenadas. Por lo tanto, no se puede predecir el orden de iteración en un diccionario o un conjunto.

Lea este artículo para saber más sobre Tipos de colección: Lenguaje de programación Swift

 2
Author: Rachit Rawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-24 19:48:20