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

时间:2018-09-22 15:38:17

标签: javascript arrays json reactjs object

我有一堆JSON,其中包含多个对象,数组,字符串,布尔值,数字等,这些对象存储在根级别和组件的一个对象中。

以下是示例:

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

我设法像这样在数组中传递了项目的路径和新值:

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

如何从那里设置该路径的新值?即。等同于:

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 个答案:

答案 0 :(得分: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; }

答案 1 :(得分:1)

下面是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')

答案 2 :(得分:0)

  1. 使用Object.key获取键Array:

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

  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]]);
            }
        }
    }
    

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