我有这个json文件:
[
{
"person": {
"@id": "value1",
"name": "Mattia"
},
"person1": {
"@ref": "value1"
},
"subPersons": [
{
"@id": "value2",
"name": "Luca",
"key": {
"@ref": "value1"
}
},
{
"@ref": "value1"
},
{
"@id": "value3",
"subsubPersons": [
{
"again": {
"@ref": "value2"
}
}
]
}
],
"key": {
"subKey": {
"@ref": "value1"
}
}
}
]
我需要映射包含@id的所有对象,所以用映射的相关@id值替换所有@ref值。我想得到这个:
[
{
"person": {
"@id": "value1",
"name": "Mattia"
},
"person1": {
"@id": "value1",
"name": "Mattia"
},
"subPersons": [
{
"@id": "value2",
"name": "Luca",
"key": {
"@id": "value1",
"name": "Mattia"
}
},
{
"@id": "value1",
"name": "Mattia"
},
{
"@id": "value3",
"subsubPersons": [
{
"again": {
"@id": "value2",
"name": "Luca",
"key": {
"@id": "value1",
"name": "Mattia"
}
}
}
]
}
],
"key": {
"subKey": {
"@id": "value1",
"name": "Mattia"
}
}
}
]
我正在使用此类替换值:
import UIKit
import Alamofire
import AlamofireObjectMapper
import ObjectMapper
import SwiftyJSON
import SwiftDate
import Async
class FindAndReplace {
var ids = Dictionary<String, JSON>()
var dictChanged = Dictionary<String, JSON>()
var isDictInit: Bool = false
/*
* Find and Replace
*/
func findAndReplace (json: JSON) -> JSON {
findJSOGids(json)
let replaced = replaceJSOGrefs(json, ids: ids)
return replaced
}
/*
* Find "@id" keys and map values related
*/
func findJSOGids (value: JSON) {
for (key, subJson): (String, JSON) in value {
if (key == "@id") {
let mValueForKey = value[key].stringValue
ids[mValueForKey] = value
}
if (subJson.type == Type.Dictionary || subJson.type == Type.Array) {
findJSOGids(subJson)
}
}
}
/*
* Replace "@ref" keys with fields mapped in ids
*/
func replaceJSOGrefs (var value: JSON, var ids: Dictionary<String, JSON>) -> JSON {
if (value.type == Type.Dictionary) {
var result = Dictionary<String, JSON> ()
for (key, subJson): (String, JSON) in value {
if (key == "@ref") {
let mValueForKey = value[key].stringValue
var isReplaced = false
while (isReplaced == false) {
for (idKey, _): (String, JSON) in ids[mValueForKey]! {
if (idKey == "@ref") {
print("found a @ref in dictionary")
let dictValueReplaced = replaceJSOGrefs(ids[mValueForKey]!, ids: ids)
ids.updateValue(dictValueReplaced, forKey: mValueForKey)
}
}
}
return ids[mValueForKey]!
} else {
result[key] = replaceJSOGrefs(subJson, ids: ids)
}
}
return JSON(result)
} else if (value.type == Type.Array) {
var result = [JSON]()
for (_, subJson): (String, JSON) in value {
result.append(replaceJSOGrefs(subJson, ids: ids))
}
return JSON(result)
} else {
return value
}
}
}
它有效,但它错过了一些@ref值。
有人可以帮帮我吗?
提前致谢。
修改
我正在使用ObjectMapper来映射对象。
答案 0 :(得分:1)
我认为查找替换方法不会有效率,因为您必须对数据进行多次传递(直到找不到任何cd sip-version
python configure.py
make
make install
字符串)。
您应该利用JSON模型引用类型语义(与值类型相反)并将其解析为这样的事实,将解析后的对象中的C:\Python
保留为错误引用。您解析的每个对象都应添加到@ref
引用的缓存中。然后在第二遍中,您将通过缓存重新布线每个引用,使用您刚刚构建为查找表的缓存。
如果每个模型都实现以下协议
@ref
您可以按模型实现它,以便为每个模型类提供自定义重新布线逻辑。以下是此类模型类的几个示例:
对于JSON中仅由@id
表示的通配符,我创建一个指针类,它只会指向引用的对象。
protocol RefObject {
func updateReferences(using cache: [String: RefObject])
}
对于一个人,你可以实现与
类似的东西{"@ref": "xxx"}
(这假设此人可以class Pointer: RefObject {
let referredId: String
var referred: RefObject!
init(referedId: String) {
self.referredId = referredId
}
func updateReferences(using cache: [String : RefObject]) {
self.referred = cache[referredId]
}
}
其中&#34;其他&#34; class Person: RefObject {
let id: String
let name: String
var otherId: String?
var other: Person?
init(id: String, name: String, otherId: String?) {
self.id = id
self.name = name
self.otherId = otherId
}
func updateReferences(using cache: [String : RefObject]) {
other = otherId.flatMap{ cache[$0] as? Person }
}
}
是可选的
这是一种通用的方法,而不是特定的实现方式,但根据您的需要,它可能是特定于域的。
更新有一个名为JSON API的类似协议(误导性名称IMO,但它使用了通过id引用JSON对象的相同方法)。这是Swift中的一个实现:https://github.com/wvteijlingen/spine可能值得一试