Подтвердить что ты не робот

Лучшая практика, чтобы узнать, имеет ли словарь SwiftyJSON ключ

Я пытаюсь найти способ получить значение ключа в словаре SwiftyJSON и вернуть строку по умолчанию, если ключ не установлен, Следующий пример работает отлично, но я не очень доволен. Вы знаете более элегантный способ?

Пример:

let users: JSON = [
    ["id": 1, "name": "one"],
    ["id": 2],
    ["id": 3, "name": "three"]
]

for (key: String, user: JSON) in users {      
    println(user.object.objectForKey("name") != nil
        ? user["name"].stringValue
        : "default")
}
4b9b3361

Ответ 2

Кажется, SwiftyJSON устанавливает свойство error, когда subscript несуществующий ключ.

Итак, это должно работать:

for (key: String, user: JSON) in users {
    let name = user["name"];
    println(name.error == nil ? name.stringValue : "default")
}

Например: с версией 6.1.1 (6A2006), ведущий ведущий: java файл SwiftyJSON:

let users: JSON = [
    ["id": 1, "name": "one"],
    ["id": 2],
    ["id": 3, "name": NSNull()],
    ["id": 4, "name": "four"],
]

for (key: String, user: JSON) in users {
    let name = user["name"];
    name.isEmpty
    println(name.error == nil ? name.stringValue : "default")
}

печатает:

one
default

four

Ответ 3

Если вам нужно проверить, есть ли в словаре SwiftyJSON ключ, вы можете сравнить его с JSON.null следующим образом:

user["name"] == JSON.null // true if the key does not exist

Используя этот метод, ваш код может выглядеть так:

let users: JSON = [
    ["id": 1, "name": "one"],
    ["id": 2],
    ["id": 3, "name": "three"]
]

for (key, user) in users {
    print(user["name"] != JSON.null ? user["name"].stringValue : "default")
}

Если вы просто хотите предоставить значение по умолчанию, вы можете использовать Nil Coalescing Operator в Swift (??) следующим образом:

let users: JSON = [
    ["id": 1, "name": "one"],
    ["id": 2],
    ["id": 3, "name": "three"]
]

for (key, user) in users {
    print(user["name"].string ?? "default")
}

SwiftJSON предоставляет метод string, который возвращает необязательное значение (String?), в отличие от stringValue, которое всегда возвращает string.

Ответ 4

Объекты типа JSON имеют рассчитанное свойство null. Это возвращает NSNull, если запрашиваемый элемент не существует, nil, если это так. Поэтому вы можете проверить наличие определенного объекта, извлекая его из родительского JSON и тестируя, чтобы узнать, существует ли свойство null. Я лично справляюсь с этим следующим образом:

let object = json["key"]
if object.null == nil {
    // Do something with 'object'
} else {
    // Key does not exist - handle the error
}

В вашем конкретном случае вы можете использовать это:

for (key: String, user: JSON) in users {
    let name = user.object.objectForKey("name")
    println(name.null == nil ? name.stringValue : "default")
}

... но так как мы знаем, что мы ищем строку, мы можем сократить ее еще больше. Все, что вам действительно нужно сделать, это отбросить часть "Значение" stringValue, так как string вернет nil, если не сможет сгенерировать строку из своего содержимого. Кроме того, проверьте оператор слияния nil ??. Он предназначен для предоставления по умолчанию для необязательных переменных, поэтому попробуйте следующее:

for (key: String, user: JSON) in users {
    println(user["name"].string ?? "default")
}

Хороший и компактный!

Ответ 5

Насколько я могу судить, это работает:

let users: JSON = [
    ["id": 1, "name": "one"],
    ["id": 2],
    ["id": 3, "name": "three"]
]

for jsonDict in users.arrayValue {      
    println(jsonDict["name"].string ?? "default")
}

Чтобы объяснить, вы хотите отнести объект JSON к типам, которые вы ожидаете получить. Если вы хотите, чтобы тип всегда был успешным (не обязательно), используйте xxxValue. Следовательно, мы отбрасываем объект root с помощью arrayValue.

arrayValue возвращает [JSON], который мы перемещаем в цикле. Нам не нужно приводить объект jsonDict: JSON к объекту, так как SwiftyJSON достаточно умен, чтобы предположить, что это dict из операторов индексов.

Наконец, пытаясь извлечь ключ из dict, затем проверьте, можно ли получить ключ в виде строки с помощью .string, который является необязательным. Используйте null coalescing для присвоения значения по умолчанию.

См. документ SwiftJSON для string и stringValue

Ответ 6

Примечание. Этот ответ больше не действителен.

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

if let name = user["name"] {    // returns optional
    // user["name"] was non-nil, is now stored in ``name""
    // do something with ``name""
} 
else {
    // user did not have key "name"
    // here would be the place to return "default"
    // or do any other error correction if the key did not exist
}