Me enfrenté a un desafío en el que necesitaba resumir una matriz de objetos por las claves del objeto. Encontré una solución, pero no puedo quitarme la sensación de que mi enfoque es bastante ingenuo:
const objArr = [ { id: 1, val: "🍊" }, { id: 1, val: "🍇" }, { id: 1, val: "🍎" }, { id: 2, val: "🥦" }, { id: 2, val: "🌽" }, { id: 2, val: "🌶" }, ]; let tempArr = []; let uniqueIdArr = []; let sortedArr = []; objArr.forEach((obj) => { tempArr.push(obj.id); uniqueIdArr = [...new Set(tempArr)]; }); uniqueIdArr.forEach((uniqueId) => { let arr = []; objArr.forEach((obj) => { if (obj.id == uniqueId) { arr.push(obj.val); } }); sortedArr.push({ id: uniqueId, vals: arr, }); }); console.log(sortedArr); // Output: [{ id: 1, vals: [ '🍊', '🍇', '🍎' ] }, { id: 2, vals: [ '🥦', '🌽', '🌶' ] }]¿Tal vez hay algo que aún no sé sobre los métodos de matriz de JavaScript? ¿Es este enfoque totalmente erróneo? ¿Hay otra forma de reducir el código y hacerlo más elegante?
Muchas preguntas...
Cualquier pista o explicación sería muy apreciada. 🙈
Gracias por adelantado
j
Nota al margen: normalmente, se supone que debe tener una id única, aparte de eso, está haciendo varias pasadas sobre la matriz de origen, lo que significa que en el peor de los casos (cuando no hay id duplicadas) obtiene O ( n²) complejidad de tiempo, por lo tanto, el tiempo de ejecución aumentará rápidamente a medida que crezca la cantidad de elementos en la matriz.
Si busca optimizar el rendimiento, probablemente pueda emplear Map junto con Array.prototype.reduce() , así:
const objArr = [ { id: 1, val: "🍊" }, { id: 1, val: "🍇" }, { id: 1, val: "🍎" }, { id: 2, val: "🥦" }, { id: 2, val: "🌽" }, { id: 2, val: "🌶" }, ] const grouppedArr = [ ...objArr .reduce((acc, {id, val}) => { const group = acc.get(id) group ? group.vals.push(val) : acc.set(id, {id, vals:[val]}) return acc }, new Map) .values() ] console.log(grouppedArr)puede usar Array.prototype.reduce para hacer su código un poco más corto:
const objArr = [ { id: 1, val: "🍊" }, { id: 1, val: "🍇" }, { id: 1, val: "🍎" }, { id: 2, val: "🥦" }, { id: 2, val: "🌽" }, { id: 2, val: "🌶" }, ]; let result = objArr.reduce((acc,e) => { let idx = acc.findIndex(s => s.id === e.id) if(idx > -1){ acc[idx].vals.push(e.val) } else{ acc.push({id:e.id,vals:[e.val]}) } return acc },[]) console.log(result)Tus ideas son buenas y explícitas, pero lejos de ser óptimas.
const objArr = [ { id: 1, val: "🍊" }, { id: 1, val: "🍇" }, { id: 1, val: "🍎" }, { id: 2, val: "🥦" }, { id: 2, val: "🌽" }, { id: 2, val: "🌶" }, ]; const idValMap = new Map(); objArr.forEach(o=>{ let vals = idValMap.get(o.id); if(!vals){ vals = []; idValMap.set(o.id,vals); } vals.push(o.val); }); console.log(Array.from(idValMap.entries()));Puede hacer la mayor parte en un solo bucle. Tome la llave, verifique si ya la vio, si no, inicialice. Eso es todo