如何创建一个函数来通过 swift 更新类内结构体键的值

问题描述 投票:0回答:1

我有一个类,其中包含一些 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
    }
}
swift
1个回答
0
投票

在 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);

© www.soinside.com 2019 - 2024. All rights reserved.