【问题标题】:Iterate through nested json object array遍历嵌套的 json 对象数组
【发布时间】:2013-03-07 10:23:00
【问题描述】:

我必须遍历 json 数组对象。

结构如下。

var myJSONObject = {
    "abc": {
        "prod_1": [
            {"prod_ver" : "prod 1 ver 1"},
            {"prod_ver" : "prod 1 ver 2"},
        ],
        "prod_2": [
            {"prod_ver" : "prod 2 ver 1"},
            {"prod_ver" : "prod 2 ver 2"},
        ],
        "prod_3": [
            {"prod_ver" : "prod 3 ver 1"},
            {"prod_ver" : "prod 3 ver 2"},
        ]
    }
};

基本上我所做的是 prod_1 是产品的名称,prod_1 的版本列表填充在其中。

所以现在我想要的是产品的名称以及它的版本。

问题是该产品下可能有许多产品和许多版本。 所以我需要一个适当的循环结构 javascript 可以通用来处理它。

如果循环将产品名称存储在一个 var 中,并将其版本存储在另一个 var 中,那将是最好的,因为我需要对产品名称进行一些检查。

如果json结构错误或者可以写出更好的json结构,请提出正确/更好的结构。

帮助

提前致谢。

【问题讨论】:

  • 那不是 JSON,那是 JavaScript 对象初始化器

标签: javascript json


【解决方案1】:

由于myJSONObject.abc 包含产品列表,因此将属性abc 定义为数组会更有意义。像这样:

var myJSONObject = 
{
"abc":
    [
        [
            {"prod_ver" : "prod 1 ver 1"},
            {"prod_ver" : "prod 1 ver 2"},
        ],
        [
            {"prod_ver" : "prod 2 ver 1"},
            {"prod_ver" : "prod 2 ver 2"},
        ],
        [
            {"prod_ver" : "prod 3 ver 1"},
            {"prod_ver" : "prod 3 ver 2"},
        ]
    ]
};

然后您可以使用正常循环迭代产品及其版本:

for(var i = 0; i < myJSONObject.abc.length; i++)
{
    var product = myJSONObject.abc[i];
    for(var j = 0; j < product.length; j++)
    {
        var version = product[j];
    }
}

您可以更进一步,稍微改变一下 JSON 对象的结构,使其更易于理解。

var catalog = 
{
    "products": [
        {
            "name": "prod 1",
            "versions": [
                "ver 1",
                "ver 2"
            ]
        },
        {
            "name": "prod 2",
            "versions": [
                "ver 1",
                "ver 2"
            ]
        }
    ]
};

for(var i = 0; i < catalog.products.length; i++)
{
    var product = catalog.products[i];
    var productName = product.name;
    for(var j = 0; j < product.versions.length; j++)
    {
        var version = product.versions[j];
    }
}

【讨论】:

  • Thanx 使用目录对象的解决方案似乎更好。
  • 很好的答案!谢谢你。如果我不知道密钥名称(即:“产品”、“名称”或“版本”),我该怎么做?
  • 我建议创建一个新问题并分享您的数据示例,以便更好地帮助您。
【解决方案2】:

myJSONObject.abc 是一个带有 prod_1prod_2 等键的对象。您可以使用 for-in 遍历对象的键。所以:

var productName;
var productVersionArray;

for (productName in myJSONObject.abc) {
    productVersionArray = myJSONObject.abc[productName];
}

请注意,键的顺序不是由规范定义的,并且会因 JavaScript 引擎而异。如果您想按特定顺序执行它们,则必须获取它们的数组,按照您想要的顺序对其进行排序,然后遍历该数组。 (在支持 ES5 的环境中,您可以从 Object.keys(yourObject) 获取对象的键数组。但对于旧版浏览器,您需要一个 shim。)

在该循环中,您可以使用标准 for 循环遍历数组:

for (versionIndex = 0; versionIndex < productVersionArray.length; ++versionIndex) {
    // Use `productVersionArray[versionIndex].prod_ver` here
}

这是一个将所有内容放在一起的示例:

(function() {

  var myJSONObject = 
    {
    "abc":
        {
            "prod_1": 
            [
                {"prod_ver" : "prod 1 ver 1"},
                {"prod_ver" : "prod 1 ver 2"}
            ],

            "prod_2": 
            [
                {"prod_ver" : "prod 2 ver 1"},
                {"prod_ver" : "prod 2 ver 2"}
            ],
            "prod_3": 
            [
                {"prod_ver" : "prod 3 ver 1"},
                {"prod_ver" : "prod 3 ver 2"}
            ]
        }
    };

  var productName;
  var productVersionArray;
  var versionIndex;

  for (productName in myJSONObject.abc) {
      productVersionArray = myJSONObject.abc[productName];
      display(productName + " has " + productVersionArray.length + " versions listed");
      for (versionIndex = 0; versionIndex < productVersionArray.length; ++versionIndex) {
        display("* " + productVersionArray[versionIndex].prod_ver);
      }
  }

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = String(msg);
    document.body.appendChild(p);
  }

})();

Live Copy | Source

【讨论】:

    【解决方案3】:

    用 ES6 更新

      var { products } =
        {
            "products": [
                {
                    "name": "prod 1",
                    "versions": [
                        "ver 1",
                        "ver 2"
                    ]
                },
                {
                    "name": "prod 2",
                    "versions": [
                        "ver 1",
                        "ver 2"
                    ]
                },
                {
                    "name": "prod 3",
                    "versions": [
                        "ver 1",
                        "ver 2"
                    ]
                }
            ]
        };
    
        let inventory = products.reduce((accumulator, currentValue) => {
            let { name, versions } = currentValue;
            accumulator[name] = versions
            return accumulator
        }, []);
    
        Object.entries(inventory).forEach((prod) => {
            let prodName = prod[0];
            let prodVers = prod[1].join(", ");
        });
    

    【讨论】:

      【解决方案4】:
      function z() {
        for (let key in myJSONObject.abc) {
          let value = myJSONObject.abc[key];
          for (let i = 0; i <= value.length; i++) {
            console.log(value[[i]]);
          }
        }
      }
      

      【讨论】:

      • 虽然您的代码可能会提供问题的答案,但请为其添加上下文/解释,以便其他人了解它的作用以及它存在的原因。
      猜你喜欢
      • 2021-07-30
      • 2018-05-13
      • 1970-01-01
      • 2020-07-25
      • 2022-01-14
      • 1970-01-01
      • 2014-01-29
      相关资源
      最近更新 更多