【问题标题】:HTML5 JSON MultiDimensional Arrays Keys with javascript or jQuery?带有 javascript 或 jQuery 的 HTML5 JSON 多维数组键?
【发布时间】:2014-12-21 00:43:46
【问题描述】:

我在网上和论坛上阅读了大量信息,但无法解决我的问题。 我有以下 JSON 文件:

var data = 
{ "AA" :[{"a1":[{"ab1": [
                     {"ab1a": 10 },
                     {"ab1b": 20 },
                     {"ab1c": 30 },
                     {"ab1d": 40 }
                     ]
            },
            {"ab2":[
                     {"ab1a": 10 },
                     {"ab1b": 20 },
                     {"ab1c": 30 },
                     {"ab1d": 40 }
                    ]
            }
            ]
     }
     ,{"a2":[{"ab3": [
                     {"ab3a": 10 },
                     {"ab3b": 20 },
                     {"ab3c": 30 },
                     {"ab3d": 40 }
                     ]
             },
            {"ab4":[
                     {"ab4a": 10 },
                     {"ab4b": 20 },
                     {"ab4c": 30 },
                     {"ab4d": 40 }
                    ]
            } 
            ]
     }    
    ]
}

我已经验证了 JSON 文件。我想首先获得"AA" 的密钥,然后是"a1""a2",然后是"ab1""ab2" 等。有关于值的问题和信息,但没有关于密钥的信息。很可能 jQuery 可能会有所帮助,但我对如何获取所有密钥感到困惑。

有什么想法吗?任何希望...!

【问题讨论】:

标签: javascript jquery json


【解决方案1】:

从未知大小的对象中获取所有键的关键是递归。在这里,我有 2 个解决方案;一个功能和一个面向对象。除了您的数据之外,我还创建了一些其他数据进行测试。

这里是包含完整代码的仓库:https://github.com/vasilionjea/json-keys


数据:

var data = {
  continents: {
    europe: {
      countries: [
        {
          'country-name': 'italy',
          cities: [
            { 'city-name': 'Rome', title: 'Roma Dolor', population:873, gdb: 301 },
            { 'city-name': 'Venice', title: 'Venice Veggies.', population:456, gdb: 244 }
          ]
        },

        {
          'country-name': 'france',
          cities: [
            { 'city-name': 'Paris', title: 'De Ipsum', population:7123, gdb: 77 },
            { 'city-name': 'Marseille', title: 'La Mipsum', population:73, gdb: 7 }
          ]
        }
      ]
    },

    'north-america': {
      countries: [
        {
          'country-name': 'canada',
          cities: [
            { 'city-name': 'Montreal', title: 'The city of lorem ipsum!', population:99, gdb: 011 },
            { 'city-name': 'Quebec', title: 'Veggie Ipsum.', population:123, gdb: 101 }
          ]
        },
        {
          'country-name': 'usa',
          cities: [
            { 'city-name': 'New York', title: 'Empire State', population:1001001, gdb: 1010 },
            { 'city-name': 'San Francisco', title: 'SF Bridge', population:20123, gdb: 202 }
          ]
        }
      ]
    }
  }
}


函数方式:

/*
 * Functional example.
 * Retrieves all keys from an object of unknown size using recursion.
 */
function _isObject(obj) {
  return Object.prototype.toString.call(obj) === "[object Object]";
}

function _eachKey(obj, callback) {
  Object.keys(obj).forEach(callback);
}

var _container = [];

function collectKeys(data) {
  _eachKey(data, function(key) {
    _container.push(key);

    if (_isObject(data[key])) {
      collectKeys(data[key]);
    }

    if (Array.isArray(data[key])) {
      // Because we're looping through an array and each array's item is an object, 
      // the `collectKeys` function is receiving each object of the array as an argument.
      data[key].forEach(collectKeys);
    }
  });

  return _container;
}

// Execute the function
var myKeys = collectKeys(data);


面向对象的方式:

/*
 * Object Oriented example.
 * Retrieves all keys from an object of unknown size using recursion.
 */
function JSONKeys(obj) {
  this._container = [];

  if (this._isObject(obj)) {
    // Just a normal object literal.
    this._data = obj;
  } else if (typeof obj === 'string') {
    // Just in case the data was passed in as a valid JSON string.
    this._data = JSON.parse(obj);
  } else {
    throw new Error('The provided argument must be an object literal or a JSON string.');
  }
}

JSONKeys.prototype = {
  constructor: JSONKeys,

  _isObject: function(obj) {
    return Object.prototype.toString.call(obj) === "[object Object]";
  },

  _eachKey: function(obj, callback) {
   // Using `bind(this)` makes sure that the `this` value in the `_collect` method 
   // isn't set to the global object (window).
    Object.keys(obj).forEach(callback.bind(this));
  },

  _recur: function(key, data) {
      // If this key's value is also an object go deeper.
      if (this._isObject(data[key])) {
        this._collect(data[key]);
      }

      if (Array.isArray(data[key])) {
        // * Because we're looping through an array and each array's item is an object, 
        //   the `_collect` method is receiving each object of the array as an argument.
        // * Using `bind(this)` makes sure that the `this` value in the `_collect` method 
        //   isn't set to the global object (window).
        data[key].forEach(this._collect.bind(this));
      }
  },

  _collect: function(data) {
    this._eachKey(data, function(key) {
      this._container.push(key);

      // Continue collecting
      this._recur(key, data);
    });
  },

  getAll: function() {
    this._collect(this._data);
    return this._container;
  }
};

// Create a new instance passing the data.
var keysObject = new JSONKeys(data);
allKeys = keysObject.getAll();

【讨论】:

  • var keys = $AA[a2][ab3].keys 是否可以通过javascript上网从ab3中获取key。
  • 是的。比如我有如下数据:var person = { addresses: [ {street: '123 main st.', number: 7, city: 'New York'}, {street: '123 first st.', number: 99, city: 'San Francisco', state: 'CA'} ] },并且想获取数组中第二个地址的key,那么我可以这样做:Object.keys(person['addresses'][1]);
  • 我到了某个地方……!我需要更多地研究在对象中访问对象。当我尝试“Object.keys(data['AA']['a2'][0]);”我得到错误数据['AA']['a2'] 未定义。
  • 那是因为data['AA'] 是一个数组,数组项可以通过一个整数(这个索引)来查询:data['AA'][0] 给你数组中的第一个对象。因此,要获得 a2,您需要使用 data['AA'][0]['a2']。但是 a2 也是一个数组,因此在该数组中获取一个对象您将遵循相同的模式。我相信你可以弄清楚其余的。 :)
猜你喜欢
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 1970-01-01
  • 2017-10-14
  • 1970-01-01
  • 2016-08-25
相关资源
最近更新 更多