Tengo una variedad de objetos,
const myArray = [{id:1, k_id:1},{id:2, k_id:2},{id:3, k_id:1},{id:4, k_id:3},{id:5, k_id:3},{id:6, k_id:2},{id:7, k_id:2},{id:8, k_id:4}]; myArray.sort((a, b) => a.k_id - b.k_id); console.log(myArray);Quiero que se ordene según el k_id y las ocurrencias (frecuencia descendente). Pero tengo que mantener todos los elementos ya que tengo otros valores en los objetos. Otros pares clave-valor pueden estar en cualquier orden. (He simplificado mi problema aquí con solo dos pares de valores clave, pero la matriz real tiene más de 15 pares de valores clave)
Salida producida:
(8) [{id:1,k_id:1},{id:3,k_id:1},{id:2,k_id:2},{id:6,k_id:2},{id:7,k_id:2},{id:4,k_id:3},{id:5,k_id:3},{id:8,k_id:4}] Salida esperada, porque necesito que se ordenen como a continuación, ya que k_id:2 ocurrió más que k_id:1 :
myArray = [{id:6, k_id:2},{id:7, k_id:2},{id:2, k_id:2},{id:3, k_id:1},{id:1, k_id:1},{id:4, k_id:3},{id:5, k_id:3},{id:8, k_id:4}];prueba esto, no estoy seguro de si escalará, pero funciona bien.
const myArray = [{id:1, k_id:1},{id:2, k_id:2},{id:3, k_id:1},{id:4, k_id:3},{id:5, k_id:3},{id:6, k_id:2},{id:7, k_id:2},{id:8, k_id:4}]; (()=>{ const keys = {} const newArray = []; /** * Determenin every keys count */ for(const one of myArray){ // if the key is not yet registered in keys // initialize 0 and add one either way // on the key count keys[one.k_id] = (keys[one.k_id] || 0) + 1; } console.log(keys) // function GetTheHighestFrequency () { /** * @return {object} highest * * containing a key or K_id * and its frequency count */ let highest = { key:0,frequency:0 }; for(const [key,value] of Object.entries(keys)){ if(value > highest.frequency) highest = { key,frequency:value }; } return highest } // // return new array for(const each of Object.keys(keys)){ // request the highest frequency key K_id const highest = GetTheHighestFrequency(); // // Add (Push) objects in the newArray // for(const one of myArray){ // add an object if // if the K_id matches the current // highest key value if(String(one.k_id) === highest.key) newArray.push(one) } delete keys[highest.key] } console.log("the result is = ",newArray) })()¿Buscas algo como esto?
inp.sort((a, b) => inp.filter(c => c.k_id === b.k_id).length - inp.filter(c => c.k_id === a.k_id).length ); // sorting a vs b by counting the occurency of each k_id property value // using filter const inp = [{id:1, k_id:1},{id:2, k_id:2},{id:3, k_id:1},{id:4, k_id:3},{id:5, k_id:3},{id:6, k_id:2},{id:7, k_id:2},{id:8, k_id:4}]; console.log( inp.sort((a, b) => inp.filter(c => c.k_id === b.k_id).length - inp.filter(c => c.k_id === a.k_id).length) )Sugeriría primero crear una búsqueda de frecuencia. A continuación, he usado reduce con Map , pero puede usar un objeto normal y un bucle for para crear la misma búsqueda. El mapa tiene claves que son k_id , y el valor de cada k_id es el número de veces que aparece k_id . Crear la búsqueda significa que no necesita recorrer su matriz en cada iteración de su tipo. Luego puede usar .sort() y ordenar por las ocurrencias para cada key_id almacenado dentro del mapa de frecuencia. Como esto usa .sort() , la clasificación es estable , por lo que los elementos con el mismo k_id mantendrán su orden relativo desde la matriz original:
const myArray = [{id:1, k_id:1},{id:2, k_id:2},{id:3, k_id:1},{id:4, k_id:3},{id:5, k_id:3},{id:6, k_id:2},{id:7, k_id:2},{id:8, k_id:4}]; const freq = myArray.reduce((acc, {k_id}) => acc.set(k_id, (acc.get(k_id) || 0) + 1), new Map); myArray.sort((a, b) => freq.get(b.k_id) - freq.get(a.k_id)); console.log(myArray);