¿Cómo hago una función que pueda transformar datos de tipo DevicesType a GroupsType a continuación? Entonces, en lugar de obtener una lista de dispositivos que indique en qué grupos están, necesito una lista de grupos que contenga sus respectivos dispositivos.
type DevicesType = { id: string name: string status: "OK" | "FAULTY" groups: { id: string name: string }[] }[] type GroupsType = { id: string name: string devices: { id: string name: string status: "OK" | "FAULTY" }[] }[]Los datos de ejemplo serían:
const devicesFromBackend: DevicesType = [ { id: "d1", name: "device 1", status: "OK", groups: [ { id: "g1", name: "group 1" }, { id: "g2", name: "group 2" } ] }, { id: "d2", name: "device 2", status: "FAULTY", groups: [ { id: "g2", name: "group 2" }, { id: "g3", name: "group 3" } ] } ];Quiero hacer esto para representar tablas para cada grupo con una lista de sus respectivos dispositivos.
A continuación se presenta una posible implementación (en JavaScript) para lograr el objetivo:
const devicesFromBackend = [ { id: "d1", name: "device 1", status: "OK", groups: [ { id: "g1", name: "group 1" }, { id: "g2", name: "group 2" } ] }, { id: "d2", name: "device 2", status: "FAULTY", groups: [ { id: "g2", name: "group 2" }, { id: "g3", name: "group 3" } ] } ]; const getGroups = (arr = devicesFromBackend) => ( Object.values( // extract only the values of the object generated arr.reduce( // iterate through the devices array using reduce (fin, {groups, ...rest}) => ({ // fin is the object generated (aggregated) ...fin, // they key (used in fin object) will be the group-id ...groups.reduce( // now iterate through the groups array (acc, {id, name}) => ({ // acc is the accumulator ...acc, // de-structured the group's name, id in above line [id]: id in fin // if the group-id already exists in fin-object ? { // populate the existing group details as-is ...fin[id], // then, add the new device into the existing group devices: fin[id].devices.concat([{ ...rest }])} // if group-id is not already present in fin, add it now : {id, name, devices: [{...rest}]} }), {} ) }), {} ) ) ); console.log(getGroups());El enfoque se explica dentro del código, como comentarios. Si es necesario, se pueden enumerar por separado en esta respuesta.
Aquí hay una posible solución que funciona con 0 dependencias.
function convertDevicesToGroups(devices: DevicesType): GroupsType { // Isolate groups const groups = devices.map((d) => d.groups). // Extract groups reduce((g, i = []) => i.concat(...g)). // Convert from 2D to 1D filter((g, i, self) => i === self.findIndex((e) => e.id === g.id)); // Remove duplicates return groups.map((group) => { const belongDevices = devices. filter((d) => d.groups.find((g) => g.id === group.id)). // Filter devices that belog to a group map((d) => ({ id: d.id, name: d.name, status: d.status })); // Extract required property return { ...group, devices: belongDevices, }; }); }Vaya al patio de juegos para ver el código y el ejemplo completos.
Además, recomendaría pequeñas mejoras en su tipo para mejorar la legibilidad.
type Group = { id: string name: string devices: { id: string name: string status: "OK" | "FAULTY" }[] } type Groups = Group[] type Device = { id: string name: string status: "OK" | "FAULTY" groups: { id: string name: string }[] } type Devices = Device[]Lo mejor sería eliminar esa dependencia circular implícita, pero requiere más refactorización que no está relacionada con su problema actual