【问题标题】:Best practice to find out if SwiftyJSON dictionary has key找出 SwiftyJSON 字典是否有键的最佳实践
【发布时间】:2015-02-15 09:51:52
【问题描述】:

我正在尝试找到一种方法来获取 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")
}

【问题讨论】:

  • 您找到解决方案了吗?谢谢!
  • @Hannes: 不,很遗憾没有
  • 我认为现在有更好的 JSON 库,在大多数用例中,ObjectMapper 工作得更好,因为它会创建对象,而不是必须通过各种字符串类型的可选字典项。

标签: swift swifty-json


【解决方案1】:

看来,当subscript 不存在键时,SwiftyJSON 设置了error 属性。

所以,这应该可行:

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

例如:w/ 版本 6.1.1 (6A2006),SwiftyJSON github 当前 master:

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

【讨论】:

【解决方案2】:

注意:此答案不再有效

似乎完美地使用了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
}

【讨论】:

【解决方案3】:

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")
}

美观小巧!

【讨论】:

  • 哎呀,刚刚意识到我的答案和你写的最后一部分几乎一样。好吧,为了更方便访问,我想我会留下答案
【解决方案4】:

据我所知,这是可行的:

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。因此,我们使用arrayValue 转换根对象。

arrayValue 返回[JSON],我们在循环中遍历它。我们不需要将 jsonDict: JSON 设置为对象,因为 SwiftyJSON 足够聪明,可以假设它是来自下标运算符的字典。

最后,尝试从字典中获取一个键,然后检查是否可以使用.string 作为字符串检索该键,这是一个可选的。使用 null 合并来分配默认值。

请参阅 stringstringValue 的 SwiftJSON 文档

【讨论】:

    【解决方案5】:

    如果您需要检查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")
    }
    

    如果你只想提供一个默认值,那么你可以像这样在 Swift (??) 中使用Nil Coalescing Operator

    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

    【讨论】:

      【解决方案6】:

      latest 版本的 SwiftyJSON 具有 exists() 函数。

      注意:他们最新的文档并没有很好的反映代码...实际的方法是exists()

      // Returns boolean
      
      json["name"].exists()
      

      【讨论】:

      • 至少在 SwiftyJSON 的 2.3.3 和 3 版本中,该方法仍然是 isExists()
      • SwiftyJSON (3.1.3) 使用.exists() 语法。
      • 对我不起作用,即使值为 null 也打印 true。
      猜你喜欢
      • 2015-09-24
      • 2017-02-10
      • 2010-09-27
      • 1970-01-01
      • 2020-10-21
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 2018-08-19
      相关资源
      最近更新 更多