Tengo una serie de elementos. Lo que quiero es agregar los elementos a un div pero de manera estratégica. Primero, agregue la clase .wrapperItems , luego agregue solo 5 elementos de la matriz y luego, si quedan más elementos en la matriz, cree un nuevo div .wrapperItems y agregue los elementos restantes de la matriz. Repita hasta que se hayan agregado todos los elementos de la matriz. ¿Cómo puedo conseguir esto? Gracias por adelantado.
Eche un vistazo a mi código HTML a continuación para tener una idea de cómo quiero que se vea la estructura.
* ¡La solución debe funcionar con cualquier longitud de matriz!
let myArray = ['test1', 'test2', 'test3', 'test4', 'test5', 'test6', 'test7', 'test8', 'test9'] $('.wrapper .wrapperItems').html('') myArray.forEach((elm) => { //add only 5 "itemCon" then create new ".wrapperItems" $('.wrapper .wrapperItems').append(`<div class="itemCon"><p>${elm}</p></div>`) }) .wrapper { display: flex; flex-direction: column; width: 100%; height: fit-content; background-color: gold; } .wrapperItems { display: flex; flex-direction: row; justify-content: center; width: 100%; height: fit-content; background-color: coral; } .itemCon { display: flex; width: 15%; height: 7vh; background-color: pink; } .itemCon p { margin: auto; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="wrapper"> <div class="wrapperItems"> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> </div> <div class="wrapperItems"> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> <div class="itemCon"> <p>test</p> </div> </div> </div>Esta es realmente una pregunta sobre cómo dividir una matriz en una matriz de matrices.
Esto se puede hacer mapeando y agrupando.
let myArray = ['test1', 'test2', 'test3', 'test4', 'test5', 'test6', 'test7', 'test8', 'test9','test10','test11']; const result = Object.values( myArray.map( (x,i) => ({grp:Math.floor(i/5),val:x})) .reduce((acc,i) => { acc[i.grp] ||= []; acc[i.grp].push(i.val); return acc; },{}) ); console.log(result); En ese punto, es solo una cuestión de forEach sobre la matriz externa donde cada elemento será una matriz de (hasta) 5 elementos
let myArray = ['test1', 'test2', 'test3', 'test4', 'test5', 'test6', 'test7', 'test8', 'test9'] const result = Object.values( myArray.map( (x,i) => ({grp:Math.floor(i/5),val:x})) .reduce((acc,i) => { acc[i.grp] ||= []; acc[i.grp].push(i.val); return acc; },{}) ); result.forEach((elm) => { //add only 5 "itemCon" then create new ".wrapperItems" const $wrapperItems = $("<div>").addClass("wrapperItems"); elm.forEach(item => { $wrapperItems.append(`<div class="itemCon"><p>${item}</p></div>`) }); $(".wrapper").append($wrapperItems); }) .wrapper { display: flex; flex-direction: column; width: 100%; height: fit-content; background-color: gold; } .wrapperItems { display: flex; flex-direction: row; justify-content: center; width: 100%; height: fit-content; background-color: coral; } .itemCon { display: flex; width: 15%; height: 7vh; background-color: pink; } .itemCon p { margin: auto; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="wrapper"> </div>Primero, divida su matriz en partes de 5.
const chunkSize = 5; function chunkify(arr, size) { for (let i = 0; i < arr.length; i++) { let toSplice = arr.splice(i, size); arr.unshift(toSplice); } return arr.reverse(); }Luego itere sobre la matriz fragmentada para obtener el resultado deseado.
const myArray = ['test1', 'test2', 'test3', 'test4', 'test5', 'test6', 'test7', 'test8', 'test9'] const chunkedArray = chunkify(myArray, chunkSize); const $parentEl = $('.wrapper'); chunkedArray.forEach((arr) => { const $wrapper = $('<div/>', { 'class': 'wrapperItems' }); arr.forEach(item => { const $itemCon = $('<div/>', { 'class': 'itemCon' }); const $p = $('<p/>', { text: item }); $itemCon.append($p); $wrapper.append($itemCon); }); $parentEl.append($wrapper); });Esta es una solución que recorre los elementos de la matriz y crea un nuevo contenedor para los divs correspondientes recién creados cada vez que se completa cada "rebanada".
Considere que solo tiene que visitar cada nodo de sus datos de entrada y comportarse con una acción en consecuencia, por lo que no es necesario crear una estructura de datos adicional solo para acercarse a la agrupación ex-post al elegir la acción a realizar.
No puedo pensar en un enfoque más legible y más eficiente que este:
let items = [ 'test1', 'test2', 'test3', 'test4', 'test5', 'test6', 'test7', 'test8', 'test9' ]; const slice = 5; const target = $('#wrapper'); let currentGroup; let itemCounter = 0; for(const item of items){ if (itemCounter++ % slice == 0) { currentGroup = $('<div></div>').addClass("wrapperItems"); $(target).append( currentGroup ); } $(currentGroup).append( $('<div></div>').addClass("itemCon") ); } .wrapper { display: flex; flex-direction: column; width: 100%; height: fit-content; background-color: gold; } .wrapperItems { display: flex; flex-direction: row; justify-content: center; width: 100%; height: fit-content; background-color: coral; border: solid blue 1px; } .itemCon { display: flex; width: 15%; height: 7vh; background-color: pink; border: solid red 1px; } .itemCon p { margin: auto; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="wrapper"> </div>