Tengo una gran fuente de datos con objetos. Lo que quería hacer es, para cada nuevo valor de cada clave, colocar el objeto en la parte superior de la matriz. Cada vez que, para cada clave, encuentro un nuevo valor, quería que el objeto subiera a esa fuente de datos. De modo que los elementos x superiores serían los x valores diferentes que pueden tener las propiedades. Así dado:
arr[0] = {name: john, age: 14, adress: xxx} arr[1] = {name: john, age: 14, adress: xxx} arr[2] = {name: marie, age: 14, adress: xxx} arr[3] = {name: marie, age: 14, adress: xxx} arr[4] = {name: john, age: 15, adress: xxx}obtendría
arr[0] = {name: john, age: 14, adress: xxx} arr[1] = {name: marie, age: 14, adress: xxx} arr[2] = {name: john, age: 15, adress: xxx} arr[3] = {name: marie, age: 14, adress: xxx} arr[4] = {name: john, age: 14, adress: xxx}Lo anterior es solo un ejemplo ficticio, ya que no siempre sé sus claves, cantidad o nombres. Lo que estoy haciendo actualmente es revisar todos los objetos y sus claves para encontrar los nuevos valores para cada clave. Al hacerlo, guarda este valor en una matriz de objetos únicos y lleva el objeto actual a la parte superior de mi matriz. Repetir este proceso para cada objeto con un valor de clave único que vaya a la segunda posición, a la tercera, y así sucesivamente. Como no siempre sé sus claves, cantidad o nombres, trato de hacer esto dinámicamente.
filterDS(dataSource){ let uniqueColumns; let i = 0; let j = 0; let temp; dataSource.forEach(data => { let keys = Object.keys(data); keys.forEach( key => { console.log(key + ":" + data[key]); uniqueColumns[key].push(data[key]); temp = dataSource[i]; j = dataSource.indexOf(data); dataSource[i] = dataSource[j]; dataSource[j] = temp; i++ }) }); return dataSource; }Sin embargo, parece atascarse al intentar leer valores indefinidos. Intenté verificar el vacío de la fuente de datos, el valor clave actual o el objeto actual del evento, pero no cambia. Se mete en un campo indefinido o vacío y se rompe. No sé qué estoy haciendo mal aquí.
Una forma de avanzar sería 'agrupar por' el nombre primero, luego iterar el grupo más largo y acceder a la matriz agrupada por índice.
const arr = [{ name: 'john', age: 14, adress: 'xxx' }, { name: 'john', age: 14, adress: 'xxx' }, { name: 'marie', age: 14, adress: 'xxx' }, { name: 'marie', age: 14, adress: 'xxx' }, { name: 'john', age: 15, adress: 'xxx' }, { name: 'tim', age: 15, adress: 'xxx' },]; // 'group by' object.name const tempMap = {}; for (const o of arr) { (tempMap[o.name] ??= []).push(o); } const groups = Object.values(tempMap); // get the length of the longest grouped array const maxLen = Math.max(...groups.map(o => o.length)) const result = []; // iterate the longest array accessing each grouped array by index for (let i = 0; i < maxLen; i++) { for (const arr of groups) { if (i < arr.length) { result.push(arr[i]); } } } console.log(result);O como una función más genérica que acepta una devolución de llamada para acceder a la/s propiedad/es para agrupar y una función de clasificación opcional para ordenar las matrices agrupadas antes de mapear el resultado
function filterDS(dataSource, getProp, sortFn) { // use the passed callback to 'group-by' const tempMap = {}; for (const o of dataSource) { (tempMap[getProp(o)] ??= []).push(o); } const groups = Object.values(tempMap); // sort if a sortFn has been passed if (typeof sortFn === 'function') { groups.sort(sortFn); } // get the length of the longest grouped array const maxLen = Math.max(...groups.map(o => o.length)) const result = []; // iterate the longest array accessing each grouped array by index for (let i = 0; i < maxLen; i++) { for (const arr of groups) { if (i < arr.length) { result.push(arr[i]); } } } return result } const arr = [{ name: 'beth', age: 14, adress: 'xxx' }, { name: 'andrew', age: 14, adress: 'xxx' }, { name: 'carrie', age: 14, adress: 'xxx' }, { name: 'xeno', age: 15, adress: 'xxx' }, { name: 'carrie', age: 14, adress: 'xxx' }, { name: 'andrew', age: 15, adress: 'xxx' }, { name: 'andrew', age: 15, adress: 'xxx' },]; console.log(filterDS(arr, (o) => o.name, (a, b) => a[0].name.localeCompare(b[0].name))); // sorted alphabetical asc. console.log(filterDS(arr, (o) => o.name)); // not sorted