如果不知道嵌套对象有多少个节点/子代,则循环嵌套对象?

时间:2018-11-11 23:19:57

标签: javascript jquery

如果我不知道嵌套对象有多少个子对象,该如何循环?

例如,如果我想用另一个对象(代码示例)更新一个旧对象,则需要逐个检查对象中的每个节点,以检查键/值是否匹配。

var savedData = {
  "a": {
    "x": {
      "foo": 1,
      "foofoo": 11
    },
    "y": {
      "bar": 2,
      "barbar": 22
    }
  },
  "b": {
    //...
  },
  "c": {
    //...
  }
};


var newData = {
  "a": {
    "x": {
      "foo": 7 //<== new value to be changed;
      //<== notice there were "foofoo" key here, we need to keep this key and does NOT remove it;
    },
    "y": {
      "bar": 8 //<== new value to be changed;
      //<== notice there were "barbar" key here, we need to keep this key and does NOT remove it;
    },
    "z": { //<== this is a brand new child object to be added to the savedData;
      "baz": 9
    }
  }
};


updateSavedData(newData);


function updateSavedData(newData) {

  if (savedData) {
    Object.keys(savedData).forEach(function(savedKeyLevel1) {
      Object.keys(newData).forEach(function(newKeyLevel1) {

        if (savedKeyLevel1 === newKeyLevel1) {
          console.log('the key [' + savedKeyLevel1 + '] exist among the saved and the new data!');
          if (jQuery.type(savedData[savedKeyLevel1]) === "object") {
            console.log('the key [' + savedKeyLevel1 + '] is an object!');
            //start looping again, but this time in a deeper level of this child object...
            Object.keys(savedData[savedKeyLevel1]).forEach(function(savedKeyLevel2) {
              Object.keys(newData[newKeyLevel1]).forEach(function(newKeyLevel2) {
                if (savedKeyLevel2 === newKeyLevel2) {
                  console.log('the key [' + savedKeyLevel1 + ' -> ' + savedKeyLevel2 + '] exist among the saved and the new data!');
                  //...
                  //<== my question is about what to do here?
                  //if I don't know how much deeper the savedData is.
                } else {
                  //this is a brand new child object, add it to the tree;
                  savedData[savedKeyLevel1][newKeyLevel2] = newData[newKeyLevel1][newKeyLevel2];
                }
              });
            });

          }
        } else {
          //this is a brand new child object, add it to the tree;
          savedData[newKeyLevel1] = newData[newKeyLevel1];
        }
      });
    });

  } else {
    savedData = newData;
  }

  console.log('The savedData after update is:\n', JSON.stringify(savedData));

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

我的问题是:

如果我不知道这些物体的深度有多深,该怎么办?

我在这里想要阅读/尝试什么?

2 个答案:

答案 0 :(得分:1)

您可能会使其变得比所需复杂一些。只要它是带有嵌套对象和属性的简单对象,就可以测试对象并递归:

var savedData = {"a": {"x": {"foo": 1,"foofoo": 11},"y": {"bar": 2,"barbar": 22}},"b": {},"c": {}};
var newData = {"a": {"x": {"foo": 7},"y": {"bar": 8 },"z": { "baz": 9}}};
  
function merge(data, newdata){
   for (let key in newdata){
      if (typeof data[key] == 'object')  merge(data[key], newdata[key])
      else data[key] = newdata[key]
    }
}
merge(savedData, newData)
console.log(savedData)
  

答案 1 :(得分:1)

马克的答案可能是最有效的。

但是,如果您真正想遍历嵌套对象,则可以使用递归:

function loopThroughNewData(newData) {
    if(newData && Object.keys(newData).length > 0) { 
        Object.keys(newData).forEach(function(newKeyLevel) {
            //do stuff
            return loopThroughNewData(newData[newKeyLevel]);
        }
    } else {
        return something;
    }
}