如何在数组中按 id 分组?

How can I group by id in a array?

我的数据数组是这样的:

let dataHospital = {
    availability: [
        {
            hosp_id: "1",
            hosp_name: "Hospital A",
            is_available: true
        },
        {
            hosp_id: "2",
            hosp_name: "Hospital B",
            is_available: false
        },
        {
            hosp_id: "3",
            hosp_name: "Hospital C",
            is_available: true
        }
    ],
    schedule: [
        {
            schedule_id: "xx1",
            hospital_id: "1",
            day: 1,
            from_time: "09:00:00",
            to_time: "13:00:00",
            hospital_name: "Hospital A",
        },
        {
            schedule_id: "xx2",
            hospital_id: "1",
            day: 2,
            from_time: "13:00:00",
            to_time: "20:00:00",
            hospital_name: "Hospital A"
        },
        {
            schedule_id: "xx3",
            hospital_id: "1",
            day: 3,
            from_time: "12:00:00",
            to_time: "23:00:00",
            hospital_name: "Hospital A"
        },
        {
            schedule_id: "xx4",
            hospital_id: "1",
            day: 4,
            from_time: "13:00:00",
            to_time: "16:00:00",
            hospital_name: "Hospital A"
        },
        {
            schedule_id: "xx5",
            hospital_id: "1",
            day: 5,
            from_time: "09:00:00",
            to_time: "13:00:00",
            hospital_name: "Hospital A"
        },
        {
            schedule_id: "xx6",
            hospital_id: "1",
            day: 6,
            from_time: "09:00:00",
            to_time: "18:00:00",
            hospital_name: "Hospital A"
        },
        {
            schedule_id: "xx7",
            hospital_id: "2",
            day: 1,
            from_time: "10:00:00",
            to_time: "14:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx8",
            hospital_id: "2",
            day: 2,
            from_time: "10:00:00",
            to_time: "14:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx9",
            hospital_id: "2",
            day: 2,
            from_time: "16:00:00",
            to_time: "18:00:00",             
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx10",
            hospital_id: "2",
            day: 3,
            from_time: "10:00:00",
            to_time: "14:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx11",
            hospital_id: "2",
            day: 3,
            from_time: "16:00:00",
            to_time: "18:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx12",
            hospital_id: "2",
            day: 4,
            from_time: "08:00:00",
            to_time: "10:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx13",
            hospital_id: "2",
            day: 5,
            from_time: "10:00:00",
            to_time: "14:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx14",
            hospital_id: "2",
            day: 6,
            from_time: "10:00:00",
            to_time: "14:00:00",
            hospital_name: "Hospital B"
        },
        {
            schedule_id: "xx15",
            hospital_id: "3",
            day: 1,
            from_time: "15:00:00",
            to_time: "17:00:00",
            hospital_name: "Hospital C"
        },
        {
            schedule_id: "xx16",
            hospital_id: "3",
            day: 4,
            from_time: "15:00:00",
            to_time: "17:00:00",
            hospital_name: "Hospital C"
        },
        {
            schedule_id: "xx17",
            hospital_id: "3",
            day: 5,
            from_time: "15:00:00",
            to_time: "17:00:00",
            hospital_name: "Hospital C",
        }
    ]
}

所以我有这样的数据数组。我想像这样更改数组:

let dataNewHospital = [
    {
        hosp_id: "1",
        hosp_name: "Hospital A",
        is_available: true,
        schedule: [
            {
                schedule_id: "xx1",
                hospital_id: "1",
                day: 1,
                from_time: "09:00:00",
                to_time: "13:00:00",
                hospital_name: "Hospital A",
            },
            {
                schedule_id: "xx2",
                hospital_id: "1",
                day: 2,
                from_time: "13:00:00",
                to_time: "20:00:00",
                hospital_name: "Hospital A"
            },
            {
                schedule_id: "xx3",
                hospital_id: "1",
                day: 3,
                from_time: "12:00:00",
                to_time: "23:00:00",
                hospital_name: "Hospital A"
            },
            {
                schedule_id: "xx4",
                hospital_id: "1",
                day: 4,
                from_time: "13:00:00",
                to_time: "16:00:00",
                hospital_name: "Hospital A"
            },
            {
                schedule_id: "xx5",
                hospital_id: "1",
                day: 5,
                from_time: "09:00:00",
                to_time: "13:00:00",
                hospital_name: "Hospital A"
            },
            {
                schedule_id: "xx6",
                hospital_id: "1",
                day: 6,
                from_time: "09:00:00",
                to_time: "18:00:00",
                hospital_name: "Hospital A"
            }
        ]
    },
    {
        hosp_id: "2",
        hosp_name: "Hospital B",
        is_available: false,
        schedule: [
            {
                schedule_id: "xx7",
                hospital_id: "2",
                day: 1,
                from_time: "10:00:00",
                to_time: "14:00:00",
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx8",
                hospital_id: "2",
                day: 2,
                from_time: "10:00:00",
                to_time: "14:00:00",
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx9",
                hospital_id: "2",
                day: 2,
                from_time: "16:00:00",
                to_time: "18:00:00",             
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx10",
                hospital_id: "2",
                day: 3,
                from_time: "10:00:00",
                to_time: "14:00:00",
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx11",
                hospital_id: "2",
                day: 3,
                from_time: "16:00:00",
                to_time: "18:00:00",
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx12",
                hospital_id: "2",
                day: 4,
                from_time: "08:00:00",
                to_time: "10:00:00",
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx13",
                hospital_id: "2",
                day: 5,
                from_time: "10:00:00",
                to_time: "14:00:00",
                hospital_name: "Hospital B"
            },
            {
                schedule_id: "xx14",
                hospital_id: "2",
                day: 6,
                from_time: "10:00:00",
                to_time: "14:00:00",
                hospital_name: "Hospital B"
            }
        ]
    },
    {
        hosp_id: "3",
        hosp_name: "Hospital C",
        is_available: true,
        schedule: [
            {
                schedule_id: "xx15",
                hospital_id: "3",
                day: 1,
                from_time: "15:00:00",
                to_time: "17:00:00",
                hospital_name: "Hospital C"
            },
            {
                schedule_id: "xx16",
                hospital_id: "3",
                day: 4,
                from_time: "15:00:00",
                to_time: "17:00:00",
                hospital_name: "Hospital C"
            },
            {
                schedule_id: "xx17",
                hospital_id: "3",
                day: 5,
                from_time: "15:00:00",
                to_time: "17:00:00",
                hospital_name: "Hospital C",
            }
        ]
    }
]

我该怎么做?

这听起来像是 Array.prototype.reduce 的工作:

dataHospital.availability.reduce((result, availability) => {
  return [
    ...result,
    {
      ...availability,
      schedule: dataHospital.schedule.filter((schedule) => {
        return schedule.hospital_id === availability.hosp_id;
      })
    }
  ]
}, []);

这是我的解决方案:

dataHospital.availability.map(el => ({ 
     ...el , 
     schedule : dataHospital.schedule.filter( sc => sc.hospital_id == el.hosp_id) };
))

你在医院上映射,并向同一个对象({...el} 制作对象的副本)注入一个新的 属性 schedule 以及具有相同 hospital_id当前的

只需 map 遍历医院,对于每家医院,filter 列出该医院的时间表,如下所示:

let dataNewHospital = dataHospital.availability.map(hospital => ({
  ...hospital,
  schedule: dataHospital.schedule.filter(schedule => schedule.hospital_id === hospital.hosp_id)
}));

上面的解决方案简洁但不是很有效,因为它 运行 遍及每个医院的 schedule 数组(这是更大的数组),理想情况下它应该 运行超过它一次。如果您有大量数据并且想要更快的方法,请尝试以下方法:

let scheduleByHospital = dataHospital.schedule.reduce((acc, schedule) => {
  acc[schedule.hospital_id] = acc[schedule.hospital_id] || [];
  acc[schedule.hospital_id].push(schedule);
  return acc;
}, Object.create(null));

let dataNewHospital = dataHospital.availability.map(hospital => ({
  ...hospital,
  schedule: scheduleByHospital[hospital.hosp_id] || []
}));