简体   繁体   English

是否可以使用 JavaScript 中的动态数组中的字符串键索引到 Object?

[英]Is it Possible to Index into an Object Using String Keys From a Dynamic Array in JavaScript?

Is it possible to dynamically set keys when using this syntax as shown in this example?如本示例所示,使用此语法时是否可以动态设置键?

In this example, the changeValue function changes the state object show at the top.在此示例中, changeValue function 更改了顶部显示的 state object。 The changeValue function takes an array of string keys to be used as a way to dynamically set the value. changeValue function 采用字符串键数组作为动态设置值的方式。

This code does not work and I am not looking for alternative approaches: (within reasonable alternation)此代码不起作用,我不是在寻找替代方法:(在合理的交替范围内)

 const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } console.log(state.profile.isFollowing) //false console.log(state.person.characteristics.gender) //male function changeValue(keys, value){ state[keys] = value } console.log(state.profile.isFollowing) //true console.log(state.person.characteristics.gender) //female changeValue(["profile", "isFollowing"], true) //<-- using an array of strings //AFTER STATE CHANGE //const state = { // profile: { // isFollowing: true, // }, // person: { // characteristics: { // gender: "male" // } // } //} changeValue(["person", "characteristics", "gender"], "female") //<-- using an array of strings //AFTER STATE CHANGE //const state = { // profile: { // isFollowing: true, // }, // person: { // characteristics: { // gender: "female" // } // } //}

I don't want to have to manually define the [keys] within the changeValue function.我不想在changeValue function 中手动定义[keys]

Is this possible?这可能吗?

Sure thing.当然可以。 A helper function like this should do the trick.像这样的助手 function 应该可以解决问题。

 const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } function changeValue(target, path, value) { for(let i = 0; i < path.length - 1; i++) { target = target[path[i]]; } target[path[path.length - 1]] = value; } console.log(JSON.stringify(state)); changeValue(state, ["profile", "isFollowing"], true); console.log(JSON.stringify(state)); changeValue(state, ["person", "characteristics", "gender"], "female"); console.log(JSON.stringify(state));

No, you can't just index into an object with an array and have it automatically descend hierarchically.不,您不能只使用数组索引 object 并让它自动按层次下降。 There are modules you can install that let you do similar things;您可以安装一些模块来做类似的事情; for example, check out lodash 's set method.例如,查看lodashset方法。 You have to join the array into a single .您必须将数组加入一个. -separated key path string, but it's basically what you're looking for. -separated key path string,但它基本上就是你要找的东西。

However, it's also pretty easy to do it yourself in vanilla JS with a loop:但是,使用循环在 vanilla JS 中自己完成它也很容易:

function changeValue(keyPath, newValue) {
    let target = state
    let key = keyPath[0]
    for (let i=1; i<keyPath.length; ++i) {
        target = target[key]
        key = keyPath[i]
    }
    target[key] = newValue;
}

Here it is in action:这是在行动:

 const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } function changeValue(keyPath, newValue) { let target = state let key = keyPath[0] for (let i=1; i<keyPath.length; ++i) { target = target[key] key = keyPath[i] } target[key] = newValue; } changeValue(["profile", "isFollowing"], true); changeValue(["person", "characteristics", "gender"], "female") console.log(state);

Another method could be to use reduce to work up the object until you get to the last item and then set it's value.另一种方法可能是使用 reduce 处理 object 直到到达最后一项,然后设置它的值。

 const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } function changeValue(keys, value){ keys.slice(0,-1).reduce((acc, k) => acc[k], state)[keys.slice(-1)] = value } changeValue(["profile", "isFollowing"], true); console.log(state); changeValue(["person", "characteristics", "gender"], "female"); console.log(state);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM