Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

202
Visualizações
Js: ¿Cuál es la forma más eficiente de clasificar una matriz de objetos en secciones?

Tengo una gran variedad de objetos, similar a esto:

 [ { id: "some_id", timestamp: 12345 }, { id: "some_other_id", timestamp: 12347 }, { id: "some_id", timestamp: 12346 }, { id: "some_other_id", timestamp: 12348 }, ... ]

Quiero ordenar la matriz de manera que haya "secciones" de objetos en la matriz, según la identificación que tenga el objeto. Dentro de cada sección, los objetos deben ordenarse de forma ascendente según la marca de tiempo. Las secciones en sí también deben ordenarse según la primera marca de tiempo de la sección. Entonces la matriz debería verse así:

 [ // section: some_id { id: "some_id", timestamp: 12345 }, { id: "some_id", timestamp: 12348 }, // section: some_other_id, comes ofter some_id section because 12346 > 12345 { id: "some_other_id", timestamp: 12346 }, { id: "some_other_id", timestamp: 12347 }, ... ]

También debería ser posible elegir entre ascender/descender en la función. Ahora mismo tengo esto:

 elements.sort((a, b) => { if (a.id === b.id) { if (sortAscending) { return a.timestamp > b.timestamp ? -1 : 1; } else { return a.timestamp > b.timestamp ? 1 : -1; } } else { return a.id.localeCompare(b.id); } })

Sin embargo, esto no ordena las secciones correctamente. ¿Algunas ideas?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

No vas a poder hacerlo de una sola manera. Tendrá que ser varios pasos ya que no sabe cuál es el mínimo.

Una forma es combinar, ordenar y luego ordenar según el más bajo.

 const data = [ { id: "a", timestamp: 4 }, { id: "b", timestamp: 3 }, { id: "a", timestamp: 2 }, { id: "b", timestamp: 1 }, ]; const x = data.reduce((a,o) => { a[o.id] = a[o.id] || []; a[o.id].push(o); return a; }, {}); const v = Object.values(x); v.forEach(x => x.sort((a,b) => a.timestamp > b.timestamp ? 1 : -1)) v.sort((a,b)=>a[0].timestamp > b[0].timestamp ? 1 : -1); const sorted = v.flat(); console.log(sorted);

La otra forma es encontrar el más bajo y luego ordenarlo.

 const data = [{ id: "a", timestamp: 4 }, { id: "b", timestamp: 3 }, { id: "a", timestamp: 2 }, { id: "b", timestamp: 1 }, ]; const smallest = data.reduce((a ,o) => { a[o.id] = Math.min(a[o.id] === undefined? Number.POSITIVE_INFINITY : a[o.id], o.timestamp); return a; }, {}); data.sort((a,b) => { return a.id === b.id ? (a.timestamp > b.timestamp ? 1 : -1) : smallest[a.id] > smallest[b.id] ? 1 : -1; }) console.log(data);

about 4 years ago · Juan Pablo Isaza Relatório

0

Esto requerirá dos pasadas a través de la matriz porque no puede ordenar por secciones hasta que sepa cuál debe ser el orden de las secciones y no lo sabrá hasta que haya visto todas las secciones y, por lo tanto, sepa cuál es la más baja o la más alta. la marca de tiempo es para cada sección (dependiendo de si está haciendo una ordenación ascendente o descendente).

Entonces, probablemente lo que tiene sentido es hacer un primer paso que recopile el valor extremo de cada sección y lo almacene en un objeto Map que puede usar como índice de clasificación de sección. Luego, puede ejecutar .sort() . Si las secciones son iguales, ordena por marca de tiempo. Si las secciones no son iguales, ordena por el valor en el índice de la sección.

 function sortByIdAndTimestamp(data, sortAscending = true) { // create a Map object where keys are id values and values are the extreme // timestamp for that id const extremeTimestamp = new Map(); for (let item of data) { if (testExtreme(item.timestamp, extremeTimestamp.get(item.id), sortAscending)) { extremeTimestamp.set(item.id, item.timestamp); } } // now just do a dual key sort data.sort((a, b) => { let result; if (a.id === b.id) { // if id is the same, just sort by timestamp result = b.timestamp - a.timestamp; } else { // if id is not the same, sort by the extreme timestamp of the id result = extremeTimestamp.get(b.id) - extremeTimestamp.get(a.id); } if (sortAscending) { result = -result; } return result; }); return data; } function testExtreme(val, extremeSoFar, sortAscending) { // determine if this id's timestamp is more extreme // than what we already have for that section return (extremeSoFar === undefined) || (sortAscending ? val < extremeSoFar : val > extremeSoFar); } const sampleData = [{ id: "some_id", timestamp: 12345 }, { id: "some_other_id", timestamp: 123 }, { id: "some_id", timestamp: 12346 }, { id: "some_other_id", timestamp: 99999 }, { id: "yet_another_id", timestamp: 1 }, { id: "yet_another_id", timestamp: 90000 }, ]; sortByIdAndTimestamp(sampleData, true); console.log(sampleData);

Nota: Cuando dijiste que querías ordenar en orden ascendente o descendente, supuse que te referías a ambas secciones y a las marcas de tiempo. Por lo tanto, una ordenación ascendente tendría primero la sección de marca de tiempo más baja y luego los elementos dentro de cada sección se ordenarían por marca de tiempo de menor a mayor. Y, una ordenación descendente tendría primero la sección de marca de tiempo más alta y luego los elementos dentro de cada sección se ordenarían por marca de tiempo de mayor a menor.

about 4 years ago · Juan Pablo Isaza Relatório

0

EDITADO: aquí hay una forma de hacerlo si entendí correctamente lo que necesita

 const data = [{ id: "some_id", timestamp: 12348 }, { id: "some_other_id", timestamp: 12346 }, { id: "some_id", timestamp: 12345 }, { id: "some_other_id", timestamp: 12347 }, { id: "X_other_id", timestamp: 12343 }, { id: "other_id", timestamp: 12349 } ] const groupById = (acc, item) => { acc[item.id] ? acc[item.id].push(item) : acc[item.id] = [item]; return acc; }; function sort(arr, bool) { const groups = Object.values(arr.reduce(groupById, {})) .map(group => group.sort((a, b) => bool ? a.timestamp - b.timestamp : b.timestamp - a.timestamp)) .sort((a, b) => bool ? a[0].timestamp - b[0].timestamp : b[0].timestamp - a[0].timestamp); return groups.flat() } console.log(sort(data, ascending = true))

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda