Reputation: 21
I have a complex JSON file that needs parsing and my loop skills (or more precisely, the lackthereof), are really failing me.
I have the following xml file, and I am trying to get all elements on one row. In my perfect world (in no particular order)...
sku #, length, width, image, description, attribute value 1, attribute value 2, attribute value 3, etc.
The JSON file is as follows:
var json = {
"product":[
{
"shipdata":{
"_length":"2in",
"_width":"2in",
},
"sku":"90245",
"brand":"Brandy",
"image":"shirt.jpg",
"description":"description",
"attributes":{
"attribute":[
{
"_name":"Color",
"_value":"Black",
},
{
"_name":"Gender",
"_value":"Mens",
},
{
"_name":"Size",
"_value":"L",
},...
So, my intended result is:
90245, Brandy, Black, Men's, L, shirt.jpg, 2in, 2in
But when I loop like the following, I only get the first result for "name". Admittedly, I'm a newb, but if anyone can push me in the right direction or show a proof of concept, it would be so so appreciated. Thanks in advance / feel horrible to even ask such a low level question.
for(var l = 0; l < json.product[i].attributes.attribute.length; l++) {
var xxx = (json.product[i].attributes.attribute[l]['_name']);
}
$('body').append(xxx);
Upvotes: 1
Views: 57
Reputation: 1933
A solution using Array.map:
var res = json.product.map(function (p) {
return [p.sku, p.brand].concat(p.attributes.attribute.map(function (at) {
return at._value;
}))
});
res.forEach(function (r) { console.log(r.join(', ')) });
https://jsfiddle.net/xve4agp6/1/
Upvotes: 0
Reputation: 5175
According to your JSON structure and the output you want, I'll suggest to do the following:
var output = Array(json.product.length); // will be an array of string
for(var i = 0; i < json.product.length; i++) {// loop on each product
output[i] = json.product[i].sku +', '+json.product[i].brand; // according to your question, seems that you want these 2 things first
for(var j = 0; j < json.product[i].attributes. attribute.length; j++){ // then we loops on the attributes
output[i] += ', ' +json.product[i].attributes. attribute[j]._name;
}
output[i] += ', ' +json.product[i].shipdata._length + ', ' + json.product[i].shipdata._width; // last we append to the string the with and height data
}
$('body').append(output)
var json = {
"product":[
{
"shipdata":{
"_length":"2in",
"_width":"2in",
},
"sku":"90245",
"brand":"Brandy",
"image":"shirt.jpg",
"description":"description",
"attributes":{
"attribute":[
{
"_name":"Color",
"_value":"Black",
},
{
"_name":"Gender",
"_value":"Mens",
},
{
"_name":"Size",
"_value":"L",
}
]
}
}
]
};
var output = Array(json.product.length); // will be an array of string
for(var i = 0; i < json.product.length; i++) {// loop on each product
output[i] = json.product[i].sku +', '+json.product[i].brand; // according to your question, seems that you want these 2 things first
for(var j = 0; j < json.product[i].attributes. attribute.length; j++){ // then we loops on the attributes
output[i] += ', ' +json.product[i].attributes. attribute[j]._name;
}
output[i] += ', ' +json.product[i].shipdata._length + ', ' + json.product[i].shipdata._width; // last we append to the string the with and height data
}
$('body').append(output)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 611
EDIT: My solution is obviously not as good as scottjustin5000 's. I'm trying to explain the detailed steps on analyzing this problem.
You want to output a string from the JSON data. So we should break the parts of the string and process one by one.
90245, Brandy, Black, Men's, L, shirt.jpg, 2in, 2in
"sku", "brand", attribute, attribute, attribute, "image", "_length", "_width"
Let's start.
function parseJSONToLine(product) {
var line = "";
line = line + product["sku"] + ", ";
line = line + product["brand"] + ", ";
line += getAllAttributes(product);
line = line + product["image"] + ", ";
line = line + product["shipdata"]["_length"] + ", ";
line = line + product["shipdata"]["_width"];
return line;
}
products = json["product"];
for (var i = 0; i < products.length; i++) {
console.log(parseJSONToLine(products[i]));
}
This part is just assembling the line your want part by part. For the attributes, we need another loop:
function getAllAttributes(product) {
var attrStr = "";
var attrsDict = {};
var attrsOrder = ["Color", "Gender", "Size"];
var attrList = product["attributes"]["attribute"];
// loop through every attribute and put it in dictionary
for (var i = 0; i < attrList.length; i++) {
attrsDict[attrList[i]["_name"]] = attrList[i]["_value"];
}
for (var i = 0; i < attrsOrder.length; i++) {
attrStr = attrStr + attrsDict[attrsOrder[i]] + ", ";
}
return attrStr;
}
The last part is to put the line produced into your HTML. Just the $(body')
line with:
$('body').append('<p>' + line + '</p>');
That's it. The point to solve this problem is to know what the line is consisted of. Then try to get the values in the JSON object one by one. When meeting something seems to be complicated, just try to write out the code and modify according to the output. console.log()
is very helpful on this.
The reason of why your code doesn't work is, your JSON data contains not only arrays but also objects. You have to take them apart.
If you need further explanation on the snippet, comment me.
JSFiddle: https://jsfiddle.net/aresowj/g9wuLg28/
Upvotes: 0
Reputation: 1346
if you don't mind using lodash, this should help you:
var res=[];
_.each(json.product, function(p) {
res.push(p.brand);
res.push(p.sku);
_.each(p.attributes.attribute, function(at) {
res.push(at._value);
});
});
console.log(res.join(','));
//Brandy,90245,Black,Mens,L
Upvotes: 1