Есть ли лучший способ получить числа из словаря (данные JSON)? - PullRequest
0 голосов
/ 15 мая 2018

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

Но переход от Any к реальному числу, такому как Float, Int, Double, кажется немного беспорядочным. Например, если я ожидаю двойное значение, но в какой-то момент сервер вернет целое число, мой код не сможет использовать:

let doubleValue = dictionary["key"] as! Double

Так что это будет работать, когда элемент 1.3, но не будет работать 1. Чтобы использовать более конкретный пример, мы можем использовать следующее:

let myDictionary: [String: Any] = [
    "myNumber_int" : 1,
    "myNumber_float" : Float(1),
    "myNumber_cgFloat" : CGFloat(1),
    "myNumber_double" : 1.0
]

let numberInt1 = myDictionary["myNumber_int"] as? Int // 1
let numberInt2 = myDictionary["myNumber_int"] as? Float // nil
let numberInt3 = myDictionary["myNumber_int"] as? CGFloat // nil
let numberInt4 = myDictionary["myNumber_int"] as? Double // nil

let numberFloat1 = myDictionary["myNumber_float"] as? Int // nil
let numberFloat2 = myDictionary["myNumber_float"] as? Float // 1
let numberFloat3 = myDictionary["myNumber_float"] as? CGFloat // nil
let numberFloat4 = myDictionary["myNumber_float"] as? Double // nil

let numberCGFloat1 = myDictionary["myNumber_cgFloat"] as? Int // nil
let numberCGFloat2 = myDictionary["myNumber_cgFloat"] as? Float // nil
let numberCGFloat3 = myDictionary["myNumber_cgFloat"] as? CGFloat // 1
let numberCGFloat4 = myDictionary["myNumber_cgFloat"] as? Double // nil

let numberDouble1 = myDictionary["myNumber_double"] as? Int // nil
let numberDouble2 = myDictionary["myNumber_double"] as? Float // nil
let numberDouble3 = myDictionary["myNumber_double"] as? CGFloat // nil
let numberDouble4 = myDictionary["myNumber_double"] as? Double // 1

Так что для каждого типа на самом деле будет работать только 1 приведение, что ... ну, я бы по крайней мере ожидал, что CGFloat сможет привести непосредственно к Double или Float ...

Так что мое решение использует NSNumber:

let myNumbers: [CGFloat] = [
    CGFloat((myDictionary["myNumber_int"] as? NSNumber)?.floatValue ?? 0.0),
    CGFloat((myDictionary["myNumber_float"] as? NSNumber)?.floatValue ?? 0.0),
    CGFloat((myDictionary["myNumber_cgFloat"] as? NSNumber)?.floatValue ?? 0.0),
    CGFloat((myDictionary["myNumber_double"] as? NSNumber)?.floatValue ?? 0.0),
] // [1,1,1,1]

Это естественно работает, но код довольно уродлив для чего-то такого простого. Но откладывая код "в сторону уродства"; мы не можем сделать подобное без использования Next Step? Я имею в виду NSNumber для чего-то столь же тривиального, как это? Я упускаю что-то очень очевидное здесь, верно?

1 Ответ

0 голосов
/ 15 мая 2018

Попробуй так: -

if let data = myDictionary as? [String: AnyObject] {
    let myNumber = data["myNumber_int"] as? Int
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...