快速过滤json数组

Posted

技术标签:

【中文标题】快速过滤json数组【英文标题】:filter array of json in swift 【发布时间】: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 不错的工具,但我认为他需要先了解可编码协议,这样他才能在未来自己处理这个问题,然后他可以跳入帮助他更快地做到这一点的工具,任何其他与我认为可以更好地帮助他的编码相关的链接。 【参考方案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 的字典的表示形式。

以上是关于快速过滤json数组的主要内容,如果未能解决你的问题,请参考以下文章

如何快速从选定的tableviewcell中过滤数组?

过滤具有特定属性 Swift 的 json 数组

使用动态条件过滤 JSON 数组

jq 过滤内部数组元素但返回整个 JSON

使用 jQuery grep() 过滤 JSON 数组

在 Typescript 中过滤 Json 数组数据