pants
pants

Reputation: 21

Parsing some JSON

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

Answers (4)

jlowcs
jlowcs

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

IsraGab
IsraGab

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

kagami
kagami

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

scottjustin5000
scottjustin5000

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

working fiddle

Upvotes: 1

Related Questions