Digamos que tenemos una matriz de objetos y la recorremos y creamos un div en cada iteración.

¿Cómo podríamos tomar la propiedad ol (que también es una matriz de objetos) en cada iteración y crear un <ol> dentro del div para cada objeto en él, con tantos <li>? como el número en la propiedad li. Además, el texto dentro de li debería ser el texto de la propiedad title por lo que debería verse así:

enter image description here

Me estoy golpeando la cabeza para solucionarlo pero mi novato no me lo permite. Probé con otro bucle del objeto ol dentro del bucle exterior, pero no puedo hacerlo bien.

var array_of_objects = [{
  "name": "john",
  "job": "pilot",
  "email": "johnpilot@gmail.com",
  "ol": [{
    "li": 6,
    "title": "6 li's"
  }, {
    "li": 2,
    "title": "2 li's"
  }, {
    "li": 5,
    "title": "5 li's"
  }]
}, {
  "name": "mark",
  "job": "engineer",
  "email": "markengineer@gmail.com",
  "ol": [{
    "li": 2,
    "title": "2 li's"
  }, {
    "li": 7,
    "title": "7 li's"
  }, {
    "li": 2,
    "title": "2 li's"
  }, {
    "li": 1,
    "title": "1 li's"
  }]
}, {
  "name": "george",
  "job": "chef",
  "email": "georgechef@gmail.com",
  "ol": [{
    "li": 1,
    "title": "1 li's"
  }, {
    "li": 3,
    "title": "3 li's"
  }, {
    "li": 4,
    "title": "4 li's"
  }, {
    "li": 3,
    "title": "3 li's"
  }, {
    "li": 3,
    "title": "3 li's"
  }]
}]

function iterate(arr) {
  arr.forEach(i => {
    var name = i.name;
    var job = i.job;
    var email = i.email;
    var ol_li = i.ol_li;
    var str = `<div>
    <span>${name}</span>
    <span>${job}</span>
    <span>${email}</span>
    <span>ol's should be placed here</span>
    </div>`
    $("body").append(str);
  })
}

iterate(array_of_objects)
div {
  display: flex;
  flex-direction: column;
  border: thin solid black;
  margin: 0.4em;
  padding: 0.2em;
}

span:not(:nth-child(4)) {
  display: flex;
  flex-direction: column;
  border: thin solid red;
  margin: 0.2em;
  padding: 0.2em;
}

span:nth-child(4) {
  display: flex;
  flex-direction: row;
  margin: 0.4em;
  padding: 0.2em;
}

ol {
  border: thin solid blue;
  margin: 0.2em;
}

li {
  margin: 0.2em;
}
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
1
VaggelisNos 5 oct. 2021 a las 11:08

2 respuestas

La mejor respuesta

Para hacer lo que necesita, puede usar map() para recorrer la matriz ol de cada objeto y crear una cadena HTML que se puede agregar al div que cree.

Tenga en cuenta el uso de fill() en el ejemplo siguiente para crear la cantidad requerida de elementos li con el mismo contenido.

También tenga en cuenta que se puede usar el mismo enfoque para ordenar el código y mejorar el rendimiento, ya que significa que solo agrega al DOM una vez cuando se completa el ciclo, en lugar de dentro de cada iteración del ciclo.

Prueba esto:

var array_of_objects = [{name:"john",job:"pilot",email:"johnpilot@gmail.com",ol:[{li:6,title:"6 li's"},{li:2,title:"2 li's"},{li:5,title:"5 li's"}]},{name:"mark",job:"engineer",email:"markengineer@gmail.com",ol:[{li:2,title:"2 li's"},{li:7,title:"7 li's"},{li:2,title:"2 li's"},{li:1,title:"1 li's"}]},{name:"george",job:"chef",email:"georgechef@gmail.com",ol:[{li:1,title:"1 li's"},{li:3,title:"3 li's"},{li:4,title:"4 li's"},{li:3,title:"3 li's"},{li:3,title:"3 li's"}]}];

function htmlFromData(arr) {
  return arr.map(obj => {
    let olHtml = obj.ol.map(ol => `<ol>${(new Array(ol.li)).fill(`<li>${ol.title}</li>`).join('')}</ol>`).join('');
    return `<div>
      <span>${obj.name}</span>
      <span>${obj.job}</span>
      <span>${obj.email}</span>
      <span>${olHtml}</span>
    </div>`    
  }).join('');
}

$("body").append(htmlFromData(array_of_objects));
div {
  display: flex;
  flex-direction: column;
  border: thin solid black;
  margin: 0.4em;
  padding: 0.2em;
}

span:not(:nth-child(4)) {
  display: flex;
  flex-direction: column;
  border: thin solid red;
  margin: 0.2em;
  padding: 0.2em;
}

span:nth-child(4) {
  display: flex;
  flex-direction: row;
  margin: 0.4em;
  padding: 0.2em;
}

ol {
  border: thin solid blue;
  margin: 0.2em;
}

li {
  margin: 0.2em;
}
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
0
Rory McCrossan 5 oct. 2021 a las 08:54

Creo que esto debería funcionar:

  • Mapee la matriz ol y coloque un solo elemento li en una variable;
  • Utilice la función repeat() para imprimirlo en la variable ol
var array_of_objects = [
  {
    "name":"john",
    "job":"pilot",
    "email":"johnpilot@gmail.com",
    "ol":[
      {"li":6,"title":"6 li's"},
      {"li":2,"title":"2 li's"},
      {"li":5,"title":"5 li's"}
    ]
  },
  {
    "name":"mark",
    "job":"engineer",
    "email":"markengineer@gmail.com",
    "ol":[
      {"li":2,"title":"2 li's"},
      {"li":7,"title":"7 li's"},
      {"li":2,"title":"2 li's"},
      {"li":1,"title":"1 li's"}
    ]
  },
  {
    "name":"george",
    "job":"chef",
    "email":"georgechef@gmail.com",
    "ol":[
      {"li":1,"title":"1 li's"},
      {"li":3,"title":"3 li's"},
      {"li":4,"title":"4 li's"},
      {"li":3,"title":"3 li's"},
      {"li":3,"title":"3 li's"}
    ]
  }
]

  function iterate(arr){

  arr.forEach(i => {

  var name = i.name;
  var job = i.job;
  var email = i.email;
  var ol_li = i.ol;
  var list = "";
  var ol = ol_li.forEach(o=>{
     l = `<li>${o.title}</li>`
     list = `${list} <ol> ${l.repeat(o.li)} </ol>`

  })
  var str = `<div>
  <span>${name}</span>
  <span>${job}</span>
  <span>${email}</span>
  <span>${list}</ol>
  </div>`

  $("body").append(str);

  })

  }

  iterate(array_of_objects)
div{
  display:flex;
  flex-direction:column;
  border:thin solid black;
  margin:0.4em;
  padding:0.2em;
}
span:not(:nth-child(4)){
  display:flex;
  flex-direction:column;
  border:thin solid red;
  margin:0.2em;
  padding:0.2em;
}
span:nth-child(4){
  display:flex;
  flex-direction:row;
  margin:0.4em;
  padding:0.2em;
}
ol{
  border:thin solid blue;
  margin:0.2em;
}
li{
  margin:0.2em;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
</head>
<body>
</body>
</html>
2
cursorrux 5 oct. 2021 a las 08:54