Reputation: 29
I'm working on an iOS app using Swift 4 and I have a dictionary like this:
var list = [
"US" : ["United-States","$"],
"FR" : ["France","€"],
"CN" :["China", "¥"]
]
I would like to sort a UITableView
based on this dictionary by the first value of each key in order to get the following result:
China
France
United-States
This this possible?
Upvotes: 0
Views: 1663
Reputation: 154631
Use map
to create an array of tuples with your country's symbol
, name
, and currency
, and then sort that array by name
:
let list = ["US" : ["United-States","$"],
"FR" : ["France","€"],
"CN" : ["China", "¥"]]
let newlist = list.map { (symbol: $0.key, name: $0.value.first ?? "", currency: $0.value.dropFirst().first ?? "")}.sorted { $0.name < $1.name }
print(newlist)
[(symbol: "CN", name: "China", currency: "¥"), (symbol: "FR", name: "France", currency: "€"), (symbol: "US", name: "United-States", currency: "$")]
This will allow you to access all of the information easily for your table:
let symbol = newlist[indexPath.row].symbol
let name = newlist[indexPath.row].name
let currency = newlist[indexPath.row].currency
or just:
let (symbol, name, currency) = newlist[indexPath.row]
For your more complicated dictionary...
One of your problems is that your value
is now [Any]
, so conditional casts are needed. Also, break up creation of the newlist
and the sorting.
let list = ["US" : ["United-States","$","My comment", 10],
"FR" : ["France","€", "My super comment", 20],
"CA" : ["Canada","$", "Whatever", 15],
"CN" : ["China", "¥", "Final comment", 5]]
let newlist = list.map { (symbol: $0.key,
name: $0.value.first as? String ?? "",
currency: $0.value.dropFirst().first as? String ?? "",
comment: $0.value.dropFirst(2).first as? String ?? "",
value: $0.value.dropFirst(3).first as? Int ?? 0) }
let sortedlist = newlist.sorted { $0.name < $1.name }
print(sortedlist)
[(symbol: "CA", name: "Canada", currency: "$", comment: "Whatever", value: 15), (symbol: "CN", name: "China", currency: "¥", comment: "Final comment", value: 5), (symbol: "FR", name: "France", currency: "€", comment: "My super comment", value: 20), (symbol: "US", name: "United-States", currency: "$", comment: "My comment", value: 10)]
Upvotes: 0
Reputation: 236418
You can get your dictionary values (arrays), map their first element and sort it:
let list = ["US" : ["United-States","$"],
"FR" : ["France","€"],
"CN" : ["China", "¥"]]
let countries = list.values.compactMap{$0.first}.sorted()
print(countries) // ["China", "France", "United-States"]
Another options is to create a struct for your currency, create a custom initializer that takes a key value pair and make it conform to Comparable protocol:
struct Currency: CustomStringConvertible, Comparable {
let name: String
let code: String
let symbol: String
init?(currency: (key: String, value: [String])) {
guard currency.value.count == 2 else { return nil }
self.code = currency.key
self.name = currency.value.first!
self.symbol = currency.value.last!
}
var description: String {
return "Code: \(code)\nName: \(name)\nSynmbol: \(symbol)\n"
}
}
extension Currency {
static func <(lhs: Currency, rhs: Currency) -> Bool {
return lhs.name < rhs.name
}
}
let list = ["US" : ["United-States","$"],
"FR" : ["France","€"],
"CN" :["China", "¥"]]
let currencies = list.compactMap(Currency.init).sorted()
currencies.map({print($0)})
This will print:
Code: CN
Name: China
Synmbol: ¥
Code: FR
Name: France
Synmbol: €
Code: US
Name: United-States
Synmbol: $
Upvotes: 2