JS重命名对象键,同时保留其在对象中的位置

时间:2018-01-03 17:15:20

标签: javascript reactjs javascript-objects state-management

修改:系统询问了与reactjs组件相关的问题,但下面的答案可以与任何js框架/代码一起使用< /强>

我的组件有这样的状态属性:

const someObj = {
  arr1: ["str1", "str2"],
  arr2: ["str3", "str4"],
}

用户可以使用输入字段编辑对象(键和值)。 当一个值改变时,我在相同的索引中替换它,然后它保持其位置,用户继续编辑在同一个地方。

更改这样的值:

handleStrChange = (e, key, strIdx) => {
  const obj = {...this.state.obj};
  obj[key][strIdx] = e.target.value;
  this.setState({
    obj
  })
}

问题是指用户更改密钥我无法重命名密钥,我需要将其删除,然后使用新名称编写新密钥,旧的价值。然后{strong>顺序obj更改结构跳转

更改这样的键:

handleKeyChange = (e, key) => {
  const obj = {...this.state.obj};
  obj[e.target.value] = obj[key]
    delete obj[key];
  this.setState({
    obj
  })
}

PLS。看一个有效的例子here

即使我需要修改obj,如何保留结构?

或者有没有办法重命名密钥而不是删除和添加新密钥?

2 个答案:

答案 0 :(得分:3)

您可能需要考虑将键数组缩减为新对象。 要做到这一点,您还需要知道哪个键更改为什么。

  1. 减少键数组
  2. 使用减少器来检查密钥更改,并在必要时进行更改。
  3. 使用值
  4. 将键添加到对象

    之后你有一个具有你以前订单的对象,并且可能更改的键仍然在同一位置

    这样的东西可能有效(未经测试)

    const changedKeyMap = {"previousKey": "newKey"};
    const keys = Object.keys(this.state.obj);
    const content = e.target.value;
    const result = keys.reduce((acc, val) => {
        // modify key, if necessary
        if (!!changedKeyMap[val]) {
            val = changedKeyMap[val];
        }
        acc[val] = content;
        // or acc[val] = this.state.obj[val] ? 
        return acc;
    }, {});
    

    如您所见,您需要跟踪您更改密钥的方式(changedKeyMap)。 reduce函数只是以正确的顺序迭代所有键,并将它们添加到新创建的对象中。如果更改了某个键,则可以在changedKeyMap中进行检查并替换它。它仍将处于正确的位置

答案 1 :(得分:1)

最后,它以js-vanila方式而不是反应方式解决。

如果有人会寻找类似的解决方案,我会发布我最终使用的代码。灵感来自Luke's想法:

const renameObjKey = ({oldObj, oldKey, newKey}) => {
  const keys = Object.keys(oldObj);
  const newObj = keys.reduce((acc, val)=>{
    if(val === oldKey){
        acc[newKey] = oldObj[oldKey];
    }
    else {
        acc[val] = oldObj[val];
    }
    return acc;
  }, {});

  return newObj;
};