如何在js中对数组中的数据进行分组
How to grouping data from array in js
我有一个包含不同对象的数组,其中每个对象都是一个 类。看起来像这样:
sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
我想把数据改成这样,(按session_id或时间分组):
sessions = [
{
session_id: 1,
time: '09:00',
classes: [
{
class_id: 1,
name: 'A',
students: [
{ student_id: 1, name: 'Adi' },
{ student_id: 1, name: 'Budi' },
],
},
{
class_id: 2,
name: 'B',
students: [
{ student_id: 3, name: 'Bayu' },
],
},
],
},
{
session_id: 2,
time: '10:00',
classes: [
{
class_id: 3,
name: 'C',
students: [
{ student_id: 6, name: 'Maha' },
],
},
{
class_id: 4,
name: 'D',
students: [
{ student_id: 7, name: 'Dede' },
],
},
],
},
];
我厌倦了尝试解决它,因为我的 javascript 不是那么好。请帮我解决代码。
您可以使用 lodash.groupBy。例如:
const sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const result = Object.entries(_.groupBy(sessions, 'session_id')).map(session => ({ session_id: Number(session[0]), time: session[1][0].time, classes: Object.entries(_.groupBy(session[1], s => s.class.class_id)).map(c => ({ class_id: Number(c[0]), name: c[1][0].class.name, students: c[1].map(x => ({ student_id: x.student.student_id, name: x.student.name })) })) }))
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
试试下面的代码片段:
const sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const newSessions = sessions.reduce((acc, session)=> {
const sessionIndex = acc.findIndex(item => item.session_id == session.session_id);
if(sessionIndex > -1){
updateSessionClasses(acc[sessionIndex], session)
}else {
acc.push({ session_id: session.session_id, time: session.time, classes: [{...session.class, students: [session.student]}] })
};
return acc;
}, []);
function updateSessionClasses(storedSession, session){
const classIndex = storedSession.classes.findIndex(c => c.class_id == session.class.class_id);
if(classIndex > -1){
storedSession.classes[classIndex].students.push(session.student)
}else {
storedSession.classes.push({...session.class, students: [session.student]})
}
}
console.log(newSessions)
我们可以使用 Array.reduce(),按 session_id 分组,然后将 class 和学生添加到每个会话(如果不存在):
const sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const result = Object.values(sessions.reduce((acc, { session_id, time, student, ['class']: { class_id, name }}) => {
acc[session_id] = acc[session_id] || { session_id, time, classes: [] };
let cl = acc[session_id].classes.find(c => c.class_id === class_id);
if (!cl) {
cl = { class_id, name, students: []}
acc[session_id].classes.push(cl);
}
cl.students.push(student);
return acc;
}, {}));
console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const studentsRedused = sessions.reduce((acc, { session_id, student, class: { class_id } }) => {
const session_class = `${session_id}-${class_id}`;
acc[session_class] = acc[session_class]
? [...acc[session_class], { ...student }]
: [{ ...student }]
return acc;
}, {});
const classesRedused = sessions.reduce((acc, { session_id, class: { class_id, name } }) => {
const needAddClass = acc[session_id] ? !acc[session_id].some((o) => o.class_id === class_id) : true
if (needAddClass) {
acc[session_id] = acc[session_id]
? [...acc[session_id], { class_id, name }]
: [{ class_id, name }]
}
return acc;
}, {});
const reduced = sessions.reduce((acc, { session_id, time, class: { class_id, name } }) => {
const classes = classesRedused[session_id].map((objClass) => {
const session_class = `${session_id}-${objClass.class_id}`;
return { ...objClass, students: studentsRedused[session_class] }
});
acc[session_id] = { session_id, time, classes }
return acc;
}, {});
const result = Object.values(reduced);
console.dir(result, {depth: null});
.as-console-wrapper { max-height: 100% !important; top: 0; }
我有一个包含不同对象的数组,其中每个对象都是一个 类。看起来像这样:
sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
我想把数据改成这样,(按session_id或时间分组):
sessions = [
{
session_id: 1,
time: '09:00',
classes: [
{
class_id: 1,
name: 'A',
students: [
{ student_id: 1, name: 'Adi' },
{ student_id: 1, name: 'Budi' },
],
},
{
class_id: 2,
name: 'B',
students: [
{ student_id: 3, name: 'Bayu' },
],
},
],
},
{
session_id: 2,
time: '10:00',
classes: [
{
class_id: 3,
name: 'C',
students: [
{ student_id: 6, name: 'Maha' },
],
},
{
class_id: 4,
name: 'D',
students: [
{ student_id: 7, name: 'Dede' },
],
},
],
},
];
我厌倦了尝试解决它,因为我的 javascript 不是那么好。请帮我解决代码。
您可以使用 lodash.groupBy。例如:
const sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const result = Object.entries(_.groupBy(sessions, 'session_id')).map(session => ({ session_id: Number(session[0]), time: session[1][0].time, classes: Object.entries(_.groupBy(session[1], s => s.class.class_id)).map(c => ({ class_id: Number(c[0]), name: c[1][0].class.name, students: c[1].map(x => ({ student_id: x.student.student_id, name: x.student.name })) })) }))
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
试试下面的代码片段:
const sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const newSessions = sessions.reduce((acc, session)=> {
const sessionIndex = acc.findIndex(item => item.session_id == session.session_id);
if(sessionIndex > -1){
updateSessionClasses(acc[sessionIndex], session)
}else {
acc.push({ session_id: session.session_id, time: session.time, classes: [{...session.class, students: [session.student]}] })
};
return acc;
}, []);
function updateSessionClasses(storedSession, session){
const classIndex = storedSession.classes.findIndex(c => c.class_id == session.class.class_id);
if(classIndex > -1){
storedSession.classes[classIndex].students.push(session.student)
}else {
storedSession.classes.push({...session.class, students: [session.student]})
}
}
console.log(newSessions)
我们可以使用 Array.reduce(),按 session_id 分组,然后将 class 和学生添加到每个会话(如果不存在):
const sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const result = Object.values(sessions.reduce((acc, { session_id, time, student, ['class']: { class_id, name }}) => {
acc[session_id] = acc[session_id] || { session_id, time, classes: [] };
let cl = acc[session_id].classes.find(c => c.class_id === class_id);
if (!cl) {
cl = { class_id, name, students: []}
acc[session_id].classes.push(cl);
}
cl.students.push(student);
return acc;
}, {}));
console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
sessions = [
{ session_id: 1, time: '09:00', student: { student_id: 1, name: 'Adi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 7, name: 'Dede' }, class: { class_id: 4, name: 'D' } },
{ session_id: 1, time: '09:00', student: { student_id: 3, name: 'Bayu' }, class: { class_id: 2, name: 'B' } },
{ session_id: 1, time: '09:00', student: { student_id: 2, name: 'Budi' }, class: { class_id: 1, name: 'A' } },
{ session_id: 2, time: '10:00', student: { student_id: 3, name: 'Maha' }, class: { class_id: 3, name: 'C' } },
];
const studentsRedused = sessions.reduce((acc, { session_id, student, class: { class_id } }) => {
const session_class = `${session_id}-${class_id}`;
acc[session_class] = acc[session_class]
? [...acc[session_class], { ...student }]
: [{ ...student }]
return acc;
}, {});
const classesRedused = sessions.reduce((acc, { session_id, class: { class_id, name } }) => {
const needAddClass = acc[session_id] ? !acc[session_id].some((o) => o.class_id === class_id) : true
if (needAddClass) {
acc[session_id] = acc[session_id]
? [...acc[session_id], { class_id, name }]
: [{ class_id, name }]
}
return acc;
}, {});
const reduced = sessions.reduce((acc, { session_id, time, class: { class_id, name } }) => {
const classes = classesRedused[session_id].map((objClass) => {
const session_class = `${session_id}-${objClass.class_id}`;
return { ...objClass, students: studentsRedused[session_class] }
});
acc[session_id] = { session_id, time, classes }
return acc;
}, {});
const result = Object.values(reduced);
console.dir(result, {depth: null});
.as-console-wrapper { max-height: 100% !important; top: 0; }