Tengo un objeto que se parece a continuación
const tableData = [ { "Location": "London", "Status": "Unknown" }, { "Location": "Delhi", "Status": "Reachable" }, { "Location": "Berlin", "Status": "Unknown" }, { "Location": "Tokyo", "Status": "Busy" }, ]Ahora quiero crear una matriz 2D que contenga esta información de cierta manera. Aquí está mi código a continuación
const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2} let statusOrderInfo = Array(Object.keys(statusOrder).length).fill([]); for(let i=0; i< tableData.length; i++) { const status = tableData[i]["Status"].trim() const statusIndex = statusOrder[status] statusOrderInfo[statusIndex].push(tableData[i]) } console.log(statusOrderInfo) Como puede ver, quiero que cada elemento del objeto tableData esté en un índice determinado de la matriz 2D. Por lo tanto, el elemento que contiene Status como Reachable debe estar en el índice 0, el elemento que contiene Status como Busy debe estar en el índice 1 y así sucesivamente.
Así que el resultado final debería verse como
[ [ { "Location":"Delhi", "Status":"Reachable" } ], [ { "Location":"Tokyo", "Status":"Busy" } ], [ { "Location":"London", "Status":"Unknown" }, { "Location":"Berlin", "Status":"Unknown" } ] ]Pero obtengo un resultado incorrecto al ejecutar el código anterior aunque estoy apuntando al índice correcto. ¿Qué hay de malo en mi enfoque?
Usando Array#reduce :
const tableData = [ { "Location": "London", "Status": "Unknown" }, { "Location": "Delhi", "Status": "Reachable" }, { "Location": "Berlin", "Status": "Unknown" }, { "Location": "Tokyo", "Status": "Busy" } ], statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}; const statusOrderInfo = tableData.reduce((list, e) => { const index = statusOrder[e.Status]; list[index] = [...(list[index] || []), {...e}]; return list; }, []); console.log(statusOrderInfo);La solución simple a su problema es simplemente cambiar su forma de establecer el valor inicial de statusOrderInfo y usar Array.from en lugar de Array.fill de esta manera:
let statusOrderInfo = Array.from({length: Object.keys(statusOrder).length}, ()=> []); otra solución es establecer el valor inicial de statusOrderInfo mediante una matriz vacía, y luego en su ciclo for, después de obtener el índice del objeto actual basado en el valor de status , puede verificar si statusIndex ya existe en statusOrderInfo o no, así:
const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2} let statusOrderInfo = []; for(let i=0; i< tableData.length; i++) { const status = tableData[i]["Status"].trim() const statusIndex = statusOrder[status]; if(statusOrderInfo[statusIndex]) statusOrderInfo[statusIndex].push(tableData[i]); else statusOrderInfo[statusIndex] = [ tableData[i] ] } console.log(statusOrderInfo); otra solución es usar el método de reduce en la matriz, así:
const tableData = [{ "Location": "London", "Status": "Unknown" }, { "Location": "Delhi", "Status": "Reachable" }, { "Location": "Berlin", "Status": "Unknown" }, { "Location": "Tokyo", "Status": "Busy" }, ]; const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2} const result = tableData.reduce((acc, cur) => { const index = statusOrder[cur.Status]; if (acc[index]) acc[index].push(cur); else acc[index] = [cur] return acc; }, []); console.log(result)Otra solución en forma declarativa:
En primer lugar, ordene los objetos por código de estado usando Array#sort
Y luego simplemente envuelva cada objeto en su propia matriz usando Array#map
const tableData = [{Location: "London",Status: "Unknown"},{Location: "Delhi",Status: "Reachable"},{Location: "Berlin",Status: "Unknown"},{Location: "Tokyo",Status: "Busy"}] const statusOrder = {Reachable: 0, Busy: 1, Unknown: 2} const result = tableData .sort(({ Status: s1 }, { Status: s2 }) => statusOrder[s1] - statusOrder[s2]) .map((item) => [item]); console.log(result); .as-console-wrapper { max-height: 100% !important; top: 0; }