2015-11-30 4 views
4

Я учусь быстро и пытаюсь понять словари. Я привык к PHP, где вы могли бы написать следующее ...Swift: отсортированный словарь

$dataPoints = Array("A"=>1,"B"=>2,"C"=>3); 
foreach($dataPoints as $value) { 
    echo($value); 
} 

В этом примере значение будет выводиться в порядке - 1, 2, 3

Моего быстр код выглядит следующим образом ...

var dataPoints: Dictionary<String,Int> = ["A":1,"B":2,"C":3] 
for (key, value) in dataPoints { 
     print(value) 
} 

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

+3

'Словари' /' NSDictionary' не сортируются в 'Swift' или' Objective-C', но посмотрите на эти http://stackoverflow.com/questions/25377177/sort-dictionary-by-keys & http://stackoverflow.com/questions/30054854/sort-a-dictionary-in-swift – sbarow

+1

Вот пользовательская реализация упорядоченного словаря: http://timekl.com/blog/2014/06/02/learning-swift- упорядоченные словари/ –

ответ

7

Как есть alr eady ответил, точка словаря в том, что он не отсортирован. Существует три типа коллекций в Swift (и Objective-C)

Массив - это упорядоченный список элементов. Используйте это, когда порядок элементов важен.

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

Комплект представляет собой мешок неупорядоченных, уникальных предметов. Используйте это, когда вы хотите иметь коллекцию уникальных предметов в определенном порядке.

Для вашего случая кажется, что заказ является для вас важным, но вы хотите сохранить какую-то пару значений.Возможно, что вы должны смотреть на это с помощью массива кортежей:

что-то вроде этого, может быть

let dataPoints = [("A", 1), ("B", 2), ("C", 3)] 

for (letter, number) in dataPoints { 
    print("\(letter), \(number)") 
} 

, который выводит

A, 1 
B, 2 
C, 3 

Альтернативно

Если вы не» t знать о порядке предметов до их создания, но есть естественный порядок, основанный на ключах, вы можете что-то сделать как это:

let dict = [ 
    "A" : 1, 
    "B" : 2, 
    "C" : 3 
] 

for key in dict.keys.sort() { 
    guard let value = dict[key] else { break } 
    print("\(key), \(value)") 
} 

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

4

От Apple docs:

В отличие от элементов в массиве, элементы в словаре не имеют определенного порядка.

Итак, нет, словарь Swift никогда не «сортируется». Тем не менее, быстрый поиск Google для "Swift упорядоченного словаря" даст несколько реализации, которая может служить вашим потребностям:

Например:

https://github.com/lukaskubanek/OrderedDictionary

https://github.com/Marxon13/M13DataStructures/blob/master/Classes/OrderedDictionary.swift

Cocoapods может также помочь:

https://cocoapods.org/?q=ordered%20dict

+0

Спасибо, Гийом, это очень полезно. У меня есть еще несколько вопросов, если вы не возражаете: 1 - Что делать, если словарь создан из строки JSON - вы никогда не знаете первоначальный заказ? 2 - Есть ли хороший тип данных ключа/значения для использования, чтобы я мог создать упорядоченный массив из них? – Ben

+3

1- Нет, что ничего не меняет, словарь никогда не сохраняет порядок. Обратите внимание, что это также относится к словарям JSON (https://stackoverflow.com/questions/7198412/keeping-dictionary-keys-of-json-object-in-order-in-objective-c), которые они не используют, У вас тоже есть заказ. 2- В зависимости от ваших потребностей вы можете хранить свои данные в массиве структур или классов, которые сохраняют порядок и имеют сильную типизацию. –

0

На всякий случай это полезно, основываясь на ответах здесь и потому, что я получаю данные от источника JSON, я решил, что лучшим вариантом было преобразование моего словаря в отсортированный массив кортежей. Я создал следующую функцию для этого:

func dictionary_to_sorted_array(dict:Dictionary<String,Int>) ->Array<(key:String,value:Int)> { 
    var tuples: Array<(key:String,value:Int)> = Array() 
    let sortedKeys = (dict as NSDictionary).keysSortedByValueUsingSelector("compare:") 
    for key in sortedKeys { 
     tuples.append((key:key as! String,value:dict[key as! String]!)) 
    } 
    return tuples 
} 

Итак, я мог бы использовать следующий код:

var dataPoints: Dictionary<String,Int> = ["A":1,"B":2,"C":3] 
dataPointsArray(dictionary_to_sorted_array(dataPoints)) 
for dataPoint in dataPointsArray { 
    print(dataPoint.value) 
} 

Я очень новичок с быстрым, так что если кто-нибудь имеет более быстрый способ делая это, это было бы здорово!

Смежные вопросы