我有一个具有以下结构的JSON响应:
GET
我已经为它创建了Swift父子结构:
父母:
{
"id": {
"sub_key1": "sub_value1",
"sub_key2": "sub_value2",
"sub_key3": "sub_value3",
"used": false
},
"key1": {
"sub_key1": "sub_value1",
"sub_key2": "sub_value2",
"sub_key3": "sub_value3",
"used": true
},
"key2": {
"sub_key1": "sub_value1",
"sub_key2": "sub_value2",
"sub_key3": "sub_value3",
"used": false
},
"key3": {
"sub_key1": "sub_value1",
"sub_key2": "sub_value2",
"sub_key3": "sub_value3",
"used": true
},
"key4": {
"sub_key1": "sub_value1",
"sub_key2": "sub_value2",
"sub_key3": "sub_value3",
"used": false
},
"key5": {
"sub_key1": "sub_value1",
"sub_key2": "sub_value2",
"sub_key3": "sub_value3",
"used": true
}
}
孩子:
struct Parent: Codable {
let id: Child?
let key1: Child?
let key2: Child?
let key3: Child?
let key4: Child?
let key5: Child?
}
现在,根据“已使用”的属性,仅使用了一些Child对象,我想过滤掉未使用的Child对象。我考虑过使用map方法,但这仅适用于数组。
关于如何解决该问题的任何想法?
答案 0 :(得分:1)
我要像这样存储Parent
:
struct Parent {
let children: [String: Child]
}
这将允许您使用parent.children.values.filter
过滤子项,并为键添加一些动态性。
作为旁注:
Swift 4.2 将允许您进行动态通话。这意味着您可以实现:
extension Parent {
subscript(dynamicMember member: String) -> Child? {
get {
return children[member]
}
set {
children[member] = newValue
}
}
}
这将使您仍然可以调用parent.key1
或parent.id
而不会失去可读性。
答案 1 :(得分:0)
首先将JSON数据转换为字典。然后,我获取该字典的值并从中创建一个数组。然后循环遍历该数组的每个字典,并将其转换为Child对象,然后将其保存在child数组(child对象的数组)中。
然后,我们将使用 filter 方法而不是map来过滤掉用作true的对象。
func fetchData() {
let dataSourceURL = URL(string: "yourURL")!
let request = URLRequest(url: dataSourceURL)
UIApplication.shared.isNetworkActivityIndicatorVisible = true
let task = URLSession(configuration: .default).dataTask(with: request) { data, response, error in
let alertController = UIAlertController(title: "Oops!",
message: "There was an error fetching json data.",
preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
alertController.addAction(okAction)
if let data = data {
do {
let yourJSONAsDict =
try PropertyListSerialization.propertyList(from: data,
options: [],
format: nil) as! [String: Any]
let valueArray = Array(yourJSONAsDict.values)
var childArray = [Child]()
for value in valueArray {
if let valueDict = value as? [String: Any] {
let childObj = Child(valueDict: valueDict)
childArray.append(childObj)
}
}
var filteredArray = childArray.filter{ ($0.used ?? false) }
print(filteredArray)
} catch {
DispatchQueue.main.async {
self.present(alertController, animated: true, completion: nil)
}
}
}
if error != nil {
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
self.present(alertController, animated: true, completion: nil)
}
}
}
task.resume()
}
这是我正在使用的Child结构,供您参考
struct Child: Codable {
let sub_key1: String?
let sub_key2: String?
let sub_key3: String?
let used: Bool?
init(valueDict: [String: Any]) {
self.sub_key1 = valueDict["sub_key1"] as? String
self.sub_key2 = valueDict["sub_key2"] as? String
self.sub_key3 = valueDict["sub_key3"] as? String
self.used = valueDict["used"] as? Bool
}
}