从键数组设置对象/数组中的嵌套项

IT技术 javascript arrays json reactjs object
2021-05-11 00:46:09

我有一堆带有多个对象、数组、字符串、布尔值、数字等的 JSON,它们存储在根级别和组件的一个对象中。

这是一个示例:

{
  "theme": {
    "auto": {
      "sensor": "sensor.sn1_ldr",
      "below": 600
    },
    "ui": {
      "cards": {
        "round": false,
        "elevation": 1
      }
    },
    ...
  },
  ...
}

我已经设法将项目的路径和新值传回数组中,如下所示:

["theme", "auto", "sensor"]

我如何从那里设置该路径的新值?IE。相当于:

config.theme.auto.sensor = newValue;

但是使用传回的路径数组?

我到目前为止的方法:

handleConfigChange = (path, value) => {
  console.log(path, value);
  let config = this.state.config;
  // Set the new value

  this.setState({ config });
};
3个回答

您可以存储最后一个键并通过从路径中获取键来减少对象。

function setValue(object, path, value) {
    var last = path.pop();
    path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}

var config = { theme: { auto: { sensor: "sensor.sn1_ldr", below: 600 }, ui: { cards: { round: false, elevation: 1 } } } },
    path = ["theme", "auto", "sensor"];

setValue(config, path, 'foo');

console.log(config);
.as-console-wrapper { max-height: 100% !important; top: 0; }

下面是 Nina 答案的一个简单版本(使用 reduce 的那个)。

希望这可以帮助您了解背后发生的事情。

const setValueByPathArray = (object, path, value) => {
  let i = 0
  let reference = object
  while (i < path.length - 1) {
    const currentPath = path[i]
    reference = reference[currentPath]
    i += 1
  }
  const lastPath = path[path.length - 1]
  reference[lastPath] = value
  return object
}

const config = { theme: { auto: { sensor: "sensor.sn1_ldr", below: 600 }, ui: { cards: { round: false, elevation: 1 } } } }
const path = ["theme", "auto", "sensor"];

setValueByPathArray(config, path, 'foo')
  1. 使用 Object.key 获取密钥数组:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

  1. 使用递归循环。

    const object1 = {
      "theme": {
        "auto": {
          "sensor": "sensor.sn1_ldr",
          "below": 600
        },
        "ui": {
          "cards": {
            "round": false,
            "elevation": 1
          }
        },
    
      },  
    }
    
    var result = [];
    see(object1);
    console.log(result);
    
    function see (obj){
        var k = Object.keys(obj)
        for (var i = 0; i < k.length; i++){
            result.push(k[i]);
            if (obj[k[i]] instanceof Object){
                see(obj[k[i]]);
            }
        }
    }