Tengo una serie de objetos:
const students = [ { name: 'Tom', class: "Blue" }, { name: 'Pom', class: "Blue" }, { name: 'Max', class: "Red" }, { name: 'Alex', class: "Red" }, { name: 'John', class: "Yellow" } ];Y me gustaría agrupar los valores devueltos por la propiedad de clase, para poder lograr algo similar a esto en HTML:
Class Blue: Tom, Pom Class Red: Max, Alex Class Yellow: Johnnota: la propiedad de clase debe mostrarse una vez como marcado HTML, razón por la cual no creo que esto ayude en absoluto ...
¿Cómo debo hacerlo? Puedo usar filter() (como a continuación) pero esto es bastante tonto. Idealmente, me gustaría evitar hacer esto varias veces, especialmente dado que la propiedad de la class es dinámica (no conocida de antemano).
const classRed = students.filter(student => student.class === "Red); const classBlue = students.filter(student => student.class === "Blue); ...Empecé este jsfiddle , pero no estoy seguro de cómo tratar este objeto para mostrar cómo lo quiero.
Supongo que esta pregunta se trata de obtener la estructura de datos correcta para poder mapearla y mostrar lo que necesito, en lugar de simplemente ordenar la matriz.
Use el método reduce para hacer el grupo por operación y use Object.entries para obtener la lista de elementos para iterar.
Prueba así
{ Object.entries( students.reduce((prevValue, currValue) => { prevValue[currValue.class] ? prevValue[currValue.class].push(currValue.name) : (prevValue[currValue.class] = [currValue.name]); return prevValue; }, {}) ).map(([classs, names]) => `Class ${classs}: ${names.join(", ")}`); } function App({}) { const students = [ { name: "Tom", class: "Blue" }, { name: "Pom", class: "Blue" }, { name: "Max", class: "Red" }, { name: "Alex", class: "Red" }, { name: "John", class: "Yellow" } ]; return ( <div> {Object.entries( students.reduce((prevValue, currValue) => { prevValue[currValue.class] ? prevValue[currValue.class].push(currValue.name) : (prevValue[currValue.class] = [currValue.name]); return prevValue; }, {}) ).map(([classs, names]) => ( <div>{`Class ${classs}: ${names.join(", ")}`}</div> ))} </div> ); } ReactDOM.render(<App />, document.getElementById("react")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="react"></div>JS violín => https://jsfiddle.net/9ahtz2jd/11/
NOTA: Siempre trate de usar las funciones de filter , map y reduce .
let classes = {}; for(let student of students) { classes[student.class] = [...classes[student.class] || [], student.name]; } console.log(classes);Podría crear un nuevo objeto con el nombre de las clases como claves y una matriz con los nombres de los estudiantes como valores.
const students = [ { name: 'Tom', class: "Blue" }, { name: 'Pom', class: "Blue" }, { name: 'Max', class: "Red" }, { name: 'Alex', class: "Red" }, { name: 'John', class: "Yellow" } ]; let klasses = {}; for (let i = 0; i < students.length; i++) { let student = students[i]; let klass = student.class; if (!klasses[klass]) { klasses[klass] = [student.name]; } else { klasses[klass].push(student.name); } } console.log(klasses);