【问题标题】:How to grouping data from array in js如何在js中对数组中的数据进行分组
【发布时间】:2022-01-13 02:51:56
【问题描述】:

我有一个包含不同对象的数组,其中每个对象都是一个类。看起来像这样:

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 不是那么好。请帮我解决代码。

【问题讨论】:

    标签: javascript arrays object mapping grouping


    【解决方案1】:

    我们可以使用Array.reduce(),按 session_id 分组,然后在每个会话中添加班级和学生(如果不存在):

    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; }

    【讨论】:

      【解决方案2】:

      您可以使用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>

      【讨论】:

      • 可读性不是很强,不过可以封装一些函数
      【解决方案3】:

      试试下面的sn-p:

      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)

      【讨论】:

        【解决方案4】:

        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; }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-16
          • 2019-02-09
          • 2020-02-18
          • 1970-01-01
          • 2022-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多