我有一个类,其中包含一些 Struct 作为属性,我可以将 json 转换为如下数据类型
var user = userData
print(userData)
/// output
/// {
/// "meals": [
/// {
/// "dinner": "beef",
/// "cloth": "A"
/// }
/// ],
/// "cars": [
/// {
/// "model": "Y",
/// "color": "white"
/// },
/// {
/// "model": "x",
/// "color": "black"
/// }
/// ]
/// }
一旦我得到数据类型。我可以像下面这样修改属性的值
print(user.meals[0].dinner) // Output: beef
userData.meals[0].dinner = "chicken"
print(user.meals[0].dinner) // Output: chicken
但是,我如何创建一个基于键路径的函数,这样我就可以做类似的事情
user.updateValue(userData, keypath: \User.meals[0].dinner, to: "chicken")
user.updateValue(userData, keypath: \User.cars[1].color, to: "red")
...
因为我不想创建多个功能来更新膳食或汽车
class User {
var name: String
init(name: String) {
self.name = name
}
}
extension User {
enum Color {
case green, yellow, red, blue
}
struct Meal {
var dinner: String
var cloth: Color
}
struct Car {
var model: String
var color: Color
}
}
在 vanilla JS 中实现此目的的解决方案:
function JSONReplace(obj, path, value) {
const keys = path.split('.');
const depth = keys.length-1;
for (let i = 0; i < depth ; i++) {
obj = obj[keys[i]];
}
if (obj && keys[depth] && obj[keys[depth]]) {
obj[keys[depth]] = value;
} else {
throw new Error("Invalid path: " + path);
}
}
传递 JSON 对象、点分隔的路径和新值作为参数。您可以根据您的需要进一步增强它。
示例用法/片段:
var userData =
{
"meals": [
{
"dinner": "beef",
"cloth": "A"
}
],
"cars": [
{
"model": "Y",
"color": "white"
},
{
"model": "x",
"color": "black"
}
]
}
function JSONReplace(obj, path, value) {
const keys = path.split('.');
const depth = keys.length-1;
for (let i = 0; i < depth ; i++) {
obj = obj[keys[i]];
}
if (obj && keys[depth] && obj[keys[depth]]) {
obj[keys[depth]] = value;
} else {
throw new Error("Invalid path: " + path);
}
}
console.log(userData);
JSONReplace(userData,'meals.0.dinner','chicken');
JSONReplace(userData,'cars.1.color','red');
console.log(userData);