最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Looping through JSON Data to Generate HTML - Stack Overflow

matteradmin3PV0评论

I have JSON data that looks like this:

data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}

I am using this data to generate HTML so it looks properly formatted and easily readable for the user. The way I am doing this is by creating a for loop to read through tennis and basketball categories. For example:

for (var i = 0; i < data.tennis.length; i++) {
  tennisProducts.push(data.tennis[i]);
  var tennisProductsTitle = tennisProducts[i].ProductName;
  var tennisProductsDescription = tennisProducts[i].Description;
  var tennisProductsPrice = tennisProducts[i].Price;
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML =
    '<h1>' + tennisProductsTitle + '</h1>' +
    '<h2>' + tennisProductsDescription + '</h1>' +
    '<div class="options-only-phone">' +
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + tennisProductsPrice + '</a>';
  document.getElementById('tennis-products-list').appendChild(badge);
}

How can I create one for loop that can read through both (or multiple) categories?

Here is my working example in this JSFiddle:

I have JSON data that looks like this:

data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}

I am using this data to generate HTML so it looks properly formatted and easily readable for the user. The way I am doing this is by creating a for loop to read through tennis and basketball categories. For example:

for (var i = 0; i < data.tennis.length; i++) {
  tennisProducts.push(data.tennis[i]);
  var tennisProductsTitle = tennisProducts[i].ProductName;
  var tennisProductsDescription = tennisProducts[i].Description;
  var tennisProductsPrice = tennisProducts[i].Price;
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML =
    '<h1>' + tennisProductsTitle + '</h1>' +
    '<h2>' + tennisProductsDescription + '</h1>' +
    '<div class="options-only-phone">' +
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + tennisProductsPrice + '</a>';
  document.getElementById('tennis-products-list').appendChild(badge);
}

How can I create one for loop that can read through both (or multiple) categories?

Here is my working example in this JSFiddle: https://jsfiddle/dsk1279b/1

Share Improve this question asked Jan 20, 2016 at 18:43 kaoscifykaoscify 1,7537 gold badges38 silver badges76 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 9

Double loop, one to iterate the object properties, the next to iterate the array:

for (var key in data) {
    for (var i = 0; i < data[key].length; i++) {
        //HTML logic
    }
}

Final code:

for (var key in data) {
    for (var i = 0; i < data[key].length; i++) {
        var title = data[key][i].ProductName;
        var desc = data[key][i].Description;
        var price = data[key][i].Price;
        var badge = document.createElement('div');
        badge.className = 'badge';
        badge.innerHTML =
            '<h1>' + title + '</h1>' +
            '<h2>' + desc + '</h1>' +
            '<div class="options-only-phone">' +
            '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + price + '</a>';
        //I gave the div the same ID's as the keys in the object for ease
        document.getElementById(key).appendChild(badge);
    }
}

data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}

for (var key in data) {
  for (var i = 0; i < data[key].length; i++) {
    var title = data[key][i].ProductName;
    var desc = data[key][i].Description;
    var price = data[key][i].Price;
    var badge = document.createElement('div');
    badge.className = 'badge';
    badge.innerHTML =
      '<h1>' + title + '</h1>' +
      '<h2>' + desc + '</h1>' +
      '<div class="options-only-phone">' +
      '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + price + '</a>';
    document.getElementById(key).appendChild(badge);
  }
}
body {
  font-family: Arial, sans-serif;
  line-height: 125%;
}

h1 {
  font-size: 0.875em;
  padding: 0;
  margin: 0;
}

h2,
a {
  font-size: 0.750em;
  padding: 0;
  margin: 0;
  font-weight: normal;
}

a:hover {
  text-decoration: none;
}

.badge {
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  padding: 12px;
  margin: 12px 0;
}

.badge:hover {
  border: 1px solid rgba(0, 0, 0, 0.3);
}
<div id="tennis">

</div>

<hr>

<div id="basketball">

</div>

tymeJV has a good approach, but this can be made even easier.

for(var product in data) {
    // logic
}

If you look at your data, you have an object that we're already iterating over in key/value form. Since you have arrays of items per key, you can use the Array.forEach() function.

for(var product in data) {
    // current is the current object in the array
    data[product].forEach(function(current){
        //HTML logic
    })
}

You change the place where you're appending the html template, so I would remend updating your data object to be something like this:

data = {
  "tennis": {
    "products: [
        {
            "Description": "Insert description here.",
            "Price": 379.99,
            "ProductName": "Babolat Play Pure Drive"
        }, 
        {
            "Description": "Insert description here.",
            "Price": 199.99,
            "ProductName": "Yonex AI 98 Tennis Racquet"
        }
    ],
    "templateTarget": '#tennis-products-list'
  }
  "basketball": 
    "products":  [
        {
            "Description": "Insert description here.",
            "Price": 64.99,
            "ProductName": "Wilson NCAA Solution Official Game Basketball"
        }, 
        {
            "Description": "Insert description here.",
            "Price": 59.99,
            "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball"
        }
    ],
      "templateTarget": '#basketball-products-list'
}

Something like that is going to allow you to do this:

for(var product in data) {
    // current is the current object in the array
    product.forEach(function(current){
        var badge = document.createElement('div');
        badge.className = 'badge';
        badge.innerHTML =
          '<h1>' + current.productName + '</h1>' +
          '<h2>' + current.description + '</h1>' +
          '<div class="options-only-phone">' +
          '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + current.price +  '</a>';
        document.getElementById(current.templateTarget).appendChild(badge);
    })
}

This can be further optimized by having that giant html string hidden in a script tag with type="text/x-template" (since the browser ignores script types it doesn't understand) and grabbing it with the innerHTML function by referencing the id property on the script tag.

Hope that helps!

Flatten the data to a single array of values with category as a property:

var _data = Object.keys(data).reduce(
              (m,c) => m.concat(data[c].map(
                (i) => (i.category = c) && i))
           , []);

console.log(_data);

Use flattened array for UI:

_data.forEach((d) => {
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML = [
    '<h1>',
    d.ProductName,
    '</h1><h2>',
    d.Description,
    '</h1><div class="options-only-phone">',
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $',
    d.Price,
    '</a>'].join('');
  document.getElementById(d.category + '-products-list').appendChild(badge);
})

'use strict';
var data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}


var _data = Object.keys(data).reduce((m,c) => m.concat(data[c].map((i) => (i.category = c) && i) ), []);

console.log(_data);


_data.forEach((d) => {
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML = [
    '<h1>',
    d.ProductName,
    '</h1><h2>',
    d.Description,
    '</h1><div class="options-only-phone">',
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $',
    d.Price,
    '</a>'].join('');
  document.getElementById(d.category + '-products-list').appendChild(badge);
})
body {
  font-family: Arial, sans-serif;
  line-height: 125%;
}

h1 {
  font-size: 0.875em;
  padding: 0; margin: 0;
}

h2, a {
  font-size: 0.750em;
  padding: 0; margin: 0;
  font-weight: normal;
}

a:hover {
  text-decoration: none;
}

.badge {
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  padding: 12px;
  margin: 12px 0;
}

.badge:hover {
    border: 1px solid rgba(0, 0, 0, 0.3);
}
<div id="tennis-products-list">

</div>

<hr>

<div id="basketball-products-list">

</div>

Post a comment

comment list (0)

  1. No comments so far