Tengo dos matrices en Javascript provenientes de Php. Combino estas matrices en una matriz.
Todos los elementos de las matrices tienen un valor created_at (Laravel). Quiero ordenar estos valores por created_at
Problema: Independientemente de su fecha. Los elementos de la primera matriz nunca tienen lugar detrás de los de la segunda matriz.
Ejemplo: B tiene la última fecha. Pero aun así, C (proviene de la segunda matriz) tiene lugar después de B.
El problema es que fusioné estas dos matrices en una matriz. Javascript todavía piensa que "hay dos matrices. Debería ordenar los elementos de la primera matriz y luego los de la segunda matriz".
lo que hago es:
history.push(...response.data[0]); // first array's values history.push(...response.data[1]); // second array's values history.sort((a, b) => { return a.created_at - b.created_at; });entonces, la historia como
[ // Comes from first array { name: 'A', created_at: '08/09/2021' }, // Comes from first array { name: 'B', created_at: '15/09/2021' }, // This third element comes from second array. { name: 'C', created_at: '08/09/2021' } ]Espero este resultado:
nuevo historial ordenado:
{ name: 'A', created_at: '08/09/2021' }, { name: 'C', created_at: '08/09/2021' }, { name: 'B', created_at: '15/09/2021' }Pero Javascript inicialmente ordena el primer elemento de la matriz. Después, ordene el segundo elemento de la matriz y luego lo que sale es:
{ name: 'A', created_at: '08/09/2021' }, { name: 'B', created_at: '15/09/2021' }, { name: 'C', created_at: '08/09/2021' },Debe enviar una función de ordenación personalizada a Array.sort()
const array = [ { name: 'A', created_at: '08/09/2021' }, { name: 'B', created_at: '15/09/2021' }, { name: 'C', created_at: '08/09/2021' } ]; const ymd = (dmy) => { let a = dmy.split('/'); return a[2] + '/' + a[1] + '/' + a[0] } const sorted = array.sort((elem1, elem2) => ymd(elem1.created_at) > ymd(elem2.created_at) ? 1 : -1); console.log(sorted);https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Editar:
Si necesita que la clasificación sea estable (lo que significa que nunca intercambia arbitrariamente objetos con valores de comparación equivalentes) o por fecha primero y segundo alfa, entonces necesitará una función de clasificación más compleja.
Con un poco más de tiempo y un formulario de sugerencia de localeCompare() Felix Kling, escribí una ordenación mejorada que es estable y ordenará primero por fecha y después por nombre.
const array = [ { name: 'A', created_at: '08/09/2021' }, { name: 'Z', created_at: '15/09/2021' }, { name: 'D', created_at: '15/09/2021' }, { name: 'B', created_at: '15/09/2021' }, { name: 'C', created_at: '08/09/2021', stable: '1'}, { name: 'S', created_at: '08/09/2020' }, { name: 'C', created_at: '08/09/2021', stable: '2' }, { name: 'C', created_at: '08/06/2021' } ]; const ymd = (dmy) => { let a = dmy.split('/'); return a[2] + '/' + a[1] + '/' + a[0] } const sorted = array.sort((elem1, elem2) => (ymd(elem1.created_at) === ymd(elem2.created_at)) ? elem1.name.localeCompare(elem2.name) : ymd(elem1.created_at).localeCompare(ymd(elem2.created_at))); console.log(sorted);Salidas:
[ { name: 'S', created_at: '08/09/2020' }, { name: 'C', created_at: '08/06/2021' }, { name: 'A', created_at: '08/09/2021' }, { name: 'C', created_at: '08/09/2021', stable: '1' }, { name: 'C', created_at: '08/09/2021', stable: '2' }, { name: 'B', created_at: '15/09/2021' }, { name: 'D', created_at: '15/09/2021' }, { name: 'Z', created_at: '15/09/2021' } ]Puede intentar fusionar la matriz primero y luego ordenar la matriz resultante:
const arr1 = [{name: 'A', created_at: '08/09/2021'},] const arr2 = [{name: 'B', created_at: '15/09/2021'}, {name: 'C', created_at: '08/09/2021'}] const result = arr1.concat(arr2).sort((a , b) => a.created_at > b.created_at) console.log(result)Para ordenar por valores de fecha, puede usar Date.prototype.getTime() :
const arr1 = [{name: 'A', created_at: '08/09/2021'}] const arr2 = [{name: 'B', created_at: '15/09/2021'}, {name: 'C', created_at: '08/09/2021'}] const toNumber= d => +d.replace(/\//g, '') const result = [...arr1, ...arr2].sort((a, b) => toNumber(a.created_at) - toNumber(b.created_at)) console.log(result)Puede array#concat tanto su matriz como usar la Schwartzian transform para ordenar su matriz convirtiendo el created_at al formato YYYY-MM-DD que podría ordenarse lexicográficamente.
const arr1 = [{name: 'A', created_at: '08/09/2021'}], arr2 = [{name: 'B', created_at: '15/09/2021'}, {name: 'C', created_at: '08/09/2021'}], result = arr1.concat(arr2) .map(o => [o.created_at.replace(/(..)\/(..)\/(....)/, '$3-$2-$1'), o]) .sort((a,b) => a[0].localeCompare(b[0])) .map(([,o]) => o); console.log(result)