快速过滤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",
]
我想得到一个只有 status
、chapter
和 correct
键值对的 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数组的主要内容,如果未能解决你的问题,请参考以下文章