【问题标题】:Iterate through entire JSON object without knowing any keys在不知道任何键的情况下遍历整个 JSON 对象
【发布时间】:2016-10-02 23:35:37
【问题描述】:

我正在尝试对我一无所知的 JSON 数据执行操作(更新值、删除键、添加键等)。这些项目本质上是属性文件,而不是从应用程序返回的 JSON 数据。这些文件可能非常不同,我需要开发一种方法来执行这些操作,而无需对 JSON 数据一无所知。

我正在跟踪存储密钥的路径。如果我有如下所示的示例数据,我将存储路径(如“/key1/innerKey5/”)并使用 getNodeData 获取键为 innerKey6 的数据。

如果我有项目的路径和密钥,我如何以编程方式在 JSON 数据中找到该项目并删除或更新该项目?

var originalData = someMethodToGetJSONData();
var currentData; // Global variable storing a copy of the original data which can be modified

json = {
  "key1": {
    "innerKey1": {
      "innerKey2" : {
        "innerKey3": "value1",
        "innerKey4": "value2"
      }
    },
    "innerKey5": {
      "innerKey6": "value1"
    }
  },
  "key2": "value3",
  "key3": "value4"
}

function getKeysFromPath(keyPath) {
  var split = keyPath.split('/');
  var keys = [];

  for(var i = 0; i < split.length; i++) {
    if(split[i] != '') {
      keys.push(split[i]);
    }
  }

  return keys
}

function getNodeData(keyPath) {
  var keys = getKeysFromPath(keyPath);
  nodeData = currentItemData;

  for(var i = 0; i < keys.length; i++) {
    nodeData = nodeData[keys[i]];
  }

  return nodeData;
}

data = getNodeData('/key1/innerKey5/');
key = 'innerKey6';
console.log('Data: ' + data[key]);

【问题讨论】:

  • 小毛病:JSON 对象只有两个属性:parsestringify。你有一个 JavaScript 对象,或者只是一个 object,而不是 JSON 对象。
  • 研究使用Object.keys()
  • @Amadan 你是对的,谢谢。

标签: javascript jquery json web


【解决方案1】:

Lodash 有一些有用的功能来做这种事情。

_.get、_.set、_.unset

因此,如果您将节点存储为字符串形式,例如。 -> a.b.c[0].k,这3个函数应该可以做你想做的。

【讨论】:

  • 这看起来是最快和最简单的选择。谢谢。
【解决方案2】:

这是一个如何遍历未知键的示例

var key;

for (key in arr) {
  if (arr.hasOwnProperty(key)) {
    console.log(key);
    console.log(arr[key]);
  }
}

【讨论】:

    【解决方案3】:

    如果您使用的是 JQuery,请使用 .each() 函数:

    $.each(json,function(key,val){
            //You may use key/val for every iteration
    });
    

    【讨论】:

      【解决方案4】:

      为了更新或删除,需要获取父对象和最后一个key:

      var lastKey = keys.pop();
      var parentObj = getNodeByKeys(keys); // refactor your code to make this function
      parentObj[lastKey] = newValue;
      delete parentObj[lastKey];
      

      【讨论】:

        【解决方案5】:

        通过 XHR 获取数据并解析 JSON:

        var getJSON = function(url) {
            return new Promise(function(resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.open('get', url, true);
                xhr.onload = function() {
                    var status = xhr.status;
                    if (status == 200) {
                        resolve(JSON.parse(xhr.response));
                    } else {
                        reject(status);
                    }
                };
                xhr.send();
            });
        };
        

        然后使用 jQuery each:

        getJSON('//yoursite.com/yourfile.json').then(function(data) {
            $.each(data, function(k, v) {
              console.log(k + ', ' + v);
            });
        }, function(status) {
            console.log(status);
        });
        

        【讨论】:

        • 如果你只是为了使用each而加入jQuery,为什么不使用$.getJSON呢?
        • 是的。我发现原生 JS XHR 很容易跨浏览器(wES6 shim),但发现在原生 JS 中迭代对象非常重要。所以$.each 很容易跨浏览器。我的偏好是原生 JS,仅此而已。
        • 在原生 JS 中你可以这样做:Object.keys(json).forEach(function(key){ });。几乎和 jQuery 一样。
        【解决方案6】:

        您可以使用此函数从“路径”获取数据:

        /**
         * Get a node from an object according to the given path.
         * @param {String} path Node's path.
         * @param {Object} data Object to retrieve the desired information.
         * @returns {Object} Returns the value from the node, or null in the
         * case the node is not found.
         */
        function getNode(path, data)
        {
            var currentNode = data;
        
            path.replace(/^\/|\/$/g, '').split('/').forEach(function(key){
                if(key in currentNode)
                {
                    currentNode = currentNode[key];
                }
                else
                {
                    currentNode = null;
                    return false;
                }
            });
        
            return currentNode;
        }
        

        从那里你可以像这样操作你的对象:

        var myData = {
            "key1": {
                "innerKey1": {
                    "innerKey2" : {
                        "innerKey3": "value1",
                        "innerKey4": "value2"
                    }
                },
                "innerKey5": {
                    "innerKey6": "value1"
                }
            },
            "key2": "value3",
            "key3": "value4"
        };
        
        var someNode = getNode('/key1/innerKey5', myData);
        
        // add value
        someNode.innerKey7 = 'newValue';
        
        // update existing value
        someNode.innerKey7 = 'otherValue';
        
        // delete value
        delete someNode.innerKey6;
        
        console.log(myData);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-11
          • 2018-11-28
          • 2011-07-04
          • 2021-01-30
          相关资源
          最近更新 更多