【问题标题】:filter array of json in swift快速过滤json数组
【发布时间】:2019-02-27 09:48:52
【问题描述】:

如何快速过滤只有某些键值对的 json 数组?

我的数组看起来像:

[{
  "status" : "true",
  "score" : "3",
  "correct" : "3",
  "chapter" : "34",
  "answer" : "342432",
  "solutionText" : "abcd",
}, {

  "status" : "true",
  "score" : "0",
  "correct" : "2",
  "chapter" : "35",
  "answer" : "35854",
  "solutionText" : "abc",

}]

我想得到一个只有 statuschaptercorrect 键值对的 json 输出数组。

喜欢:

[{
  "status" : "true",
  "correct" : "3",
  "chapter" : "34",
}, {

  "status" : "true",
  "correct" : "2",
  "chapter" : "35",
}]

【问题讨论】:

  • 你能告诉我们你已经做了什么吗?
  • 使用Decodable 并仅使用所需的键/成员声明结构。很简单。
  • 嘿,如果你想要一些能让你为 JSON 创建结构或类的东西。请试试这个app.quicktype.io
  • @TheiOSDev 不错的工具,但我认为他需要先了解可编码协议,这样他才能在未来自己处理这个问题,然后他可以跳入帮助他更快地做到这一点的工具,任何其他与我认为可以更好地帮助他的编码相关的链接。

标签: ios arrays json swift


【解决方案1】:

考虑到这是您的JSON

var myJSON = """
[{
    "status" : "true",
    "score" : "3",
    "correct" : "3",
    "chapter" : "34",
    "answer" : "342432",
    "solutionText" : "abcd"
    }, {

        "status" : "true",
        "score" : "0",
        "correct" : "2",
        "chapter" : "35",
        "answer" : "35854",
        "solutionText" : "abc"

    }]
"""

像这样简单地创建一个Decodable struct

typealias  MyArray = [MyObject] // Use this to decode 

struct MyObject: Codable {
    let status, correct, chapter: String
}

并像这样使用它

//Usage
var myJSONData = myJSON.data(using: .utf8)! // converting the JSON to data 
let objArray = try! JSONDecoder().decode(MyArray.self, from: myJSONData) // decoding the json data into an object


   //how to access
print(objArray.count)// number of elements in my array
print(objArray.first!) // getting the first object
 let myObject =  obj[0] // also getting the first object by index
 myObject.chapter
 myObject.correct
 myObject.status

了解Codable here

【讨论】:

  • 你的答案看起来和已经添加的不一样吗? ,而且您并不清楚您讨论的错误
  • @Sh_Khan 在此处了解Codable,我相信他可以为每个步骤得到所有可能的解释,+ 已经回答了关于 SO 的问题,如果您指的是,我没有复制粘贴您的答案to,我不知道是谁先发布的,但如果你愿意,如果它给你带来任何问题,我可以删除它
  • @Sh_Khan 如果这是一个罕见的案例,我们肯定会作为一个社区的所有人解决它并尝试获得解释等,但它的直接案例已经发布了太多次,我什至为什么这个问题还没有结束,有点奇怪没有在线或smth的mods
  • @MohmmadS 我的输出看起来像[quizApp.SessionReport.MyObject(status: "true", correct: "1", chapter: "35")] 如何仅获取 JSON 数组?
  • 它是那个数组,但它会打印出这样的对象^_^尝试这些命令,你会明白print(obj.count)// 2 print(obj.first!)
【解决方案2】:

如果它已经在一个对象中,你可以试试

filteredArray = myArray.map { ["status": $0.status, "correct": $0.correct, "chapter": $0.chapter]  }

【讨论】:

    【解决方案3】:

    你可以试试

    do {
        
        let res = try JSONDecoder().decode([Root].self, from:data)
     
    }
    catch {
        
        print(error)
    }
    

    struct Root: Codable {
      let status, correct, chapter: String
    }
    

    正确的json

    [{
        "status" : "true",
        "score" : "3",
        "correct" : "3",
        "chapter" : "34",
        "answer" : "342432",
        "solutionText" : "abcd"
        }, {
            
            "status" : "true",
            "score" : "0",
            "correct" : "2",
            "chapter" : "35",
            "answer" : "35854",
            "solutionText" : "abc"
            
    }]
    

    更适合做

    状态是布尔值而不是字符串

    正确&章节为整数

    所以 json 看起来像

    [{
        "status" : true,
        "score" : "3",
        "correct" : 3,
        "chapter" : 34,
        "answer" : "342432",
        "solutionText" : "abcd"
        }, {
            
            "status" : true,
            "score" : "0",
            "correct" : 2,
            "chapter" : 35,
            "answer" : "35854",
            "solutionText" : "abc"
            
    }]
    

    如果需要,您还可以设置其他类似的值,那么您的模型将如下所示

    struct Root: Codable {
      let status: Bool
      let correct, chapter: Int
    }
    

    编辑:

    let data = try content.rawData() // this inside do block
    

    其中content 的类型为JSON

    【讨论】:

    • do catch 的目的是什么?
    • 当您遇到解码错误时很有用,例如添加一个在 json 中不存在或存在但具有不同类型或错误输入正确键名的非可选键,这将有助于跟踪解决它的问题
    • 是的,ofc,但我的意思是在这种情况下,它不像那种非常简单直接的关键.. ? 可能我认为就可以了
    • 这是建议初学者的最佳实践,即使 100% 肯定不会抛出任何错误
    • @Sh_Khan 收到此错误无法将类型“[JSON]”的值转换为预期的参数类型“数据”
    【解决方案4】:

    试试Decodable的swift

    class MyObjectsClass : Decodable {
       var objects : [Objects]?
    }
    
    class Objects : Decodable {
       var status : String?
       var correct : String?
       var chapter : String?
    }
    

    解码时

    let decodedValue = try? JSONDecoder.decode(MyObjectsClass.self, from : data)
    // where data from API calls
    

    【讨论】:

    • 这行不通,为什么一个类以及为什么所有属性都是可选的?
    • 因为 JSON 的根对象不是字典。
    • 这不是字典,我还没有声明字典。
    • 您确实已经声明了带有不存在的键 objects 的字典的表示形式。
    猜你喜欢
    • 1970-01-01
    • 2015-10-27
    • 2014-09-11
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    相关资源
    最近更新 更多