I working on an app to show some information about cities
In an array I have two parameters 1- languages (I don't know how many there are) 2- the number of people that speak on that language
I get this data from an server
here is this two paramter in JSon
"language": "French",
"number": "12321",
these data among other data is saved in an array
I Just want to get the most used language with the pecentage for example French with 35% how can I do it in swift?
Your help will be appreciated.
import Foundation
let serverOutput = Data("""
[
{
"language": "French",
"number": "12"
},
{
"language": "English",
"number": "10"
}
]
""".utf8)
struct LangueUsers: Codable {
let language: String
let number: Int
enum CodingKeys: CodingKey {
case language
case number
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
language = try container.decode(String.self, forKey: .language)
let rawNumber = try container.decode(String.self, forKey: .number)
guard let number = Int(rawNumber) else {
throw DecodingError.typeMismatch(Int.self, DecodingError.Context(codingPath: [CodingKeys.number], debugDescription: "\(rawNumber) can't be convert to Int"))
}
self.number = number
}
}
struct LangueUsersPercent: CustomStringConvertible {
let language: String
let share: Double
init(language: String, number: Int, all: Int) {
self.language = language
self.share = Double(number) / Double(all)
}
var description: String {
return String(format: "%@ - %0.1f%%", language, share * 100)
}
}
let decoder = JSONDecoder()
//1
var output = try decoder.decode([LangueUsers].self, from: serverOutput)
//2
let allUser = output.reduce(0) { (reult, languageUsers) -> Int in
reult + Int(languageUsers.number)
}
//3
output.sort { (lhs, rhs) -> Bool in
lhs.number > rhs.number
}
//4
let response = output.map {
LangueUsersPercent(language: $0.language, number: $0.number, all: allUser)
}
print(response[0])
The code assumes that the output from a server is in serverOutput
variable. So steps need to achieve your task:
LangueUsers
) using swift codable. Keep in mind that by default it won't convert string values to int, so I have to create a custom init(from decoder: Decoder)
initializerHope this is clear for you. Let me know if you have any questions.