遍历嵌套的JSON对象数组

18

我需要遍历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中,可以通用地处理它。
最好的情况是循环将产品名称存储在一个变量中,将其版本存储在另一个变量中,因为我需要检查产品名称。
如果json结构错误或者可以编写更好的json结构,请建议正确/更好的结构。
请帮忙!
提前致谢。

这不是 JSON,而是 JavaScript 对象初始化器。 - T.J. Crowder
4个回答

21

由于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];
    }
}

谢谢,使用目录对象的解决方案似乎更好。 - Saurabh
非常好的答案!谢谢。如果我不知道键名(例如:“产品”,“名称”或“版本”),我该怎么做呢? - iSofia
我建议您创建一个新的问题并分享您数据的示例,这样可以更好地得到帮助。 - Korijn

8

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)从对象中获取键的数组。但是,您需要为旧版浏览器提供支持。)
在循环内部,您可以使用标准的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


2

使用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(", ");
    });

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

2
虽然你的代码可能提供了问题的答案,但请添加上下文/解释,以便其他人了解它的作用和原因。 - Theo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接