2016-12-05 4 views
3
var arr:Array<Dictionary<String, String>> = [["title":"Mrs","name":"Abc"],["title":"Mr","name":"XYZ"]] 
arr.sort { (<#[String : String]#>, <#[String : String]#>) -> Bool in 
     <#code#> 
    } 

У меня есть набор словарей с форматом данных, представленным выше. Я хочу отсортировать этот массив на имя ключ. Я сделал это в старшем быстром виде:Сортировка в swift 3.0

arr.sort{$0.name < $1.name} 

который больше не работает. Пожалуйста, дайте мне знать, как продвигаться вперед по этой структуре и сортировать ее.

Спасибо.

+4

Я единственный, кто думает о «@MartinR приходит !!»? :) –

+2

Точечная нотация не работает в * старше swift *. – vadian

+0

Согласен, не могу видеть, когда он может работать. Я бы использовал, если позволить поймать значение имени, но если вы хотите что-то короткое 'arr.sorted {$ 0 [" name "]! <$ 1 ["name"]! } ' – Dam

ответ

5

У вас есть массив словарей вида [String: String] и словарь не имеет name свойства, так $0.name является недействительным (в любого Swift версии).

Получение значения словаря осуществляется посредством подписки, , например. $0["name"], который возвращает факультативно. В Swift 2 вы можете сравнить опционы напрямую (и nil был считался "less" чем любое значение, отличное от nil). Поэтому в Swift 2 можно сортировать массив с

arr.sortInPlace { $0["name"] < $1["name"] } 

Однако необязательные операторы сравнения были удалены в Swift 3 с реализацией SE-0121 – Remove Optional Comparison Operators.

Поэтому вы должны развернуть $0["name"]. Если вы 100% уверены, что каждый словарь в массиве имеет «имя» ключ , то вы можете разворачивать силой в Ahmad F suggested

arr.sort { $0["name"]! < $1["name"]! } 

Если это не гарантируется, то укажите имя по умолчанию, например, пустая строка через оператор ноль-коалесцирующего ??:

arr.sort { ($0["name"] ?? "") < ($1["name"] ?? "") } 

Пример:

var arr = [["title":"Mrs","name":"Abc"], ["title":"Mr","name":"XYZ"], ["title": "Dr"]] 
arr.sort { ($0["name"] ?? "") < ($1["name"] ?? "") } 
print(arr) 
// [["title": "Dr"], ["name": "Abc", "title": "Mrs"], ["name": "XYZ", "title": "Mr"]] 

Как можно видеть, словарь без ключа «имени» заказан первым. Простой способ сортировки записей без имени последний было бы:

arr.sort { ($0["name"] ?? "\u{10FFFF}") < ($1["name"] ?? "\u{10FFFF}") } 
+0

Благодарим за разъяснения. В случае, если ключ не является «именем», есть ли способ дать [«title»: «Dr»] (или все словари без ключа «name») в конце заказа? –

+1

@AhmadF. См. Обновление. –

+1

@dfri: Это тот случай? Сорт нестабилен. –

4

На самом деле, я не уверен, что если arr.sort{$0.name < $1.name} работал в «старой быстры», однако, она должна быть как:

var arr:Array<Dictionary<String, String>> = [["title":"Mr","name":"XYZ"], ["title":"Mrs","name":"Abc"]] 

print(arr) // [["name": "XYZ", "title": "Mr"], ["name": "Abc", "title": "Mrs"]] 

arr.sort { 
    ($0["name"])! < ($1["name"])! 
} 

print(arr) // [["name": "Abc", "title": "Mrs"], ["name": "XYZ", "title": "Mr"]] 

Надеется, что это помогло.

+1

Предполагая, что каждый словарь имеет поле' name' ... –

+0

Это было в более раннем порядке. Не работает в swift 3. Пожалуйста, посмотрите на ожидаемый синтаксис. –

+0

@MadhupSinghYadav Я реализовал это на детской площадке, Xcode 8.1 ... –