最新消息: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 - convert JSON object to html string - Stack Overflow

matteradmin8PV0评论

I have a JSON:

    const json = {
  "name": "superman",
  "place": "universe",
  "pets": [
    {
      "id": "1",
      "type": "dog",
      "name": "Drogo"
    },
    {
      "id": "2",
      "type": "cat",
      "name": "Cindy"
    }
  ]
};

The requirement is to change this to a html string like so:

'<body><div>superman</div><div>universe</div><div><p>1</p><p>dog</p><p>Drogo</p><p>2</p><p>cat</p><p>Cindy</p></div></body>'

I wrote the below function to solve it. Basically I am iterating through json using Object.entries to obtain [key, value] pair and then appending the value to myStr, my final string variable. But I cannot retain the strings thus formed.

let myStr = ""; // initialize String
const printString = (o, myStr) => {
  if (typeof o === "string") {
    myStr += "<div>" + `${o}` + "</div><br>";
  }
  return myStr;
};
const getString = json => {
  for (let [key, value] of Object.entries(json)) {
    printString(value, myStr);
    if (Array.isArray(value)) {
      value.forEach(item => {
        printString(item, myStr);
      });
    }
  }
  return myStr;
};

const htmlString = "<body>" + getString(json) + "</body>";

console.log(htmlString);

I need some help with my logic. Further, I have a few issues:

i) How do I write 1 function that contains all of these features, including myStr variable, such that my code is modular ii) Why isn't myStr able to remember previous string? iii) In such type of problems, is it wise to just go through the specific json object and iterate through it or there should be a more generic function that checks for object, string or Array within the json and then generates string accordingly?

I have a JSON:

    const json = {
  "name": "superman",
  "place": "universe",
  "pets": [
    {
      "id": "1",
      "type": "dog",
      "name": "Drogo"
    },
    {
      "id": "2",
      "type": "cat",
      "name": "Cindy"
    }
  ]
};

The requirement is to change this to a html string like so:

'<body><div>superman</div><div>universe</div><div><p>1</p><p>dog</p><p>Drogo</p><p>2</p><p>cat</p><p>Cindy</p></div></body>'

I wrote the below function to solve it. Basically I am iterating through json using Object.entries to obtain [key, value] pair and then appending the value to myStr, my final string variable. But I cannot retain the strings thus formed.

let myStr = ""; // initialize String
const printString = (o, myStr) => {
  if (typeof o === "string") {
    myStr += "<div>" + `${o}` + "</div><br>";
  }
  return myStr;
};
const getString = json => {
  for (let [key, value] of Object.entries(json)) {
    printString(value, myStr);
    if (Array.isArray(value)) {
      value.forEach(item => {
        printString(item, myStr);
      });
    }
  }
  return myStr;
};

const htmlString = "<body>" + getString(json) + "</body>";

console.log(htmlString);

I need some help with my logic. Further, I have a few issues:

i) How do I write 1 function that contains all of these features, including myStr variable, such that my code is modular ii) Why isn't myStr able to remember previous string? iii) In such type of problems, is it wise to just go through the specific json object and iterate through it or there should be a more generic function that checks for object, string or Array within the json and then generates string accordingly?

Share Improve this question asked Sep 14, 2019 at 20:30 theusualtheusual 7913 gold badges11 silver badges28 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 2

Or, maybe, do it this way?

const json = {
  name: "superman",
  place: "universe",
  pets: [
    {
      id: "1",
      type: "dog",
      name: "Drogo"
    },
    {
      id: "2",
      type: "cat",
      name: "Cindy"
    }
  ]
};

function mkhtml(js){
  return Object.values(js).map(v=>
'<div>'+((typeof v)=='object'
   ?v.map(e=> '<p>'+Object.values(e).join('</p><p>')+'<p>').join('')
   :v)+'</div>').join('');
}
console.log(mkhtml(json));

And the same again, with conventional function syntax:

const json = {
  name: "superman",
  place: "universe",
  pets: [
    {
      id: "1",
      type: "dog",
      name: "Drogo"
    },
    {
      id: "2",
      type: "cat",
      name: "Cindy"
    }
  ]
};

function mkhtml(js){
  return Object.values(js).map(function(v){
    return '<div>'+((typeof v)=='object'
     ?v.map(function(e){return '<p>'+Object.values(e).join('</p><p>')+'<p>'}).join('')
     :v)+'</div>';
  }).join('');
}
console.log(mkhtml(json));

I just converted the last remaining arrow function to the "old" function form again.

The logic:

The outer .map() works on all the array Object.values() of the object that is stored in the variable json: for each value v a new <div> is created which is then filled with either the value v itself or a series of <p> elements in case v turns out to be an object (actually, it is an array of objects!) In this case the <p>s are filled with the values of each array element's object.

It looks a bit ugly but still works, If you know how deep your array is then I wouldn't go with recursion.

Working proof: https://jsfiddle/bajuck9y/

JS

let html = '';
for (const key in json) {
  if (!Array.isArray(json[key])) {
    html += '<div>' + json[key] + '</div>'
  } else {
    html += '<div>';
    for (const item of json[key]) {
      for (const key2 in item) {
        html += '<p>' + item[key2] + '</p>'
      }

    }
    html += '</div>';

  }

}

You were not adding the items in the property which was an array of Objects, you can use Object.values() to iterate over the values and append to the <p> tag.

Also you did not re-assign the new string formed in the printString() function back to the myStr variable, so as a result the new string that was generated was lost.

This is because string is immutable appending a new string to an older one will create a new instance of a string:

const json = {
  name: "superman",
  place: "universe",
  pets: [
    {
      id: "1",
      type: "dog",
      name: "Drogo"
    },
    {
      id: "2",
      type: "cat",
      name: "Cindy"
    }
  ]
};

let myStr = ""; // initialize String
const printString = (o, myStr, tag) => {
  if (typeof o === "string") {
    myStr += `<${tag}> ${o} </${tag}>`;
  }else if(typeof o === "object"){
    Object.values(o).forEach(val => myStr += `<${tag}> ${val} </${tag}>`);
  }
  return myStr;
};
const getString = json => {
  for (let [key, value] of Object.entries(json)) {
   if (Array.isArray(value)) {
      myStr += "<div>"
      value.forEach(item => {
        myStr = printString(item, myStr, "p");
      });
      myStr += "</div>"
   }else{
     myStr = printString(value, myStr, "div");
   }
  }
 return myStr;
};
const htmlString = "<body>" + getString(json) + "</body>";

console.log(htmlString);

If you want it to be more modular maybe you could split out your function into a number of small function helpers:

const json = {"name":"superman","place":"universe","pets":[{"id":"1","type":"dog","name":"Drogo"},{"id":"2","type":"cat","name":"Cindy"}]};

// Return a string given string and el args
const toEl = (str, el) => `<${el}>${str}</${el}>`;

// Call toEl with a string and 'div' param
const toDiv = (str) => toEl(str, 'div');

// Call toEl with a string and 'p' param
const toPara = (str) => toEl(str, 'p');

// Iterate over the array, and then
// iterate over each object calling getPara
// for each value
function getArr(arr) {
  return arr.map(obj => {
    return Object.values(obj).map(v => {
      return toPara(v);
    }).join('');
  }).join('');
}

// Now just join it all together
function getHTMLString(obj) {
  const name = toDiv(obj.name);
  const place = toDiv(obj.place);
  const pets = toDiv(getArr(obj.pets));
  return `<body>${name}${place}${pets}</body>`; 
}

console.log(getHTMLString(json));

Post a comment

comment list (0)

  1. No comments so far