5
votes

Trier les objets par valeur avec lodash

J'ai un objet qui ressemble à ceci:

_.orderBy(tempCount, Number, ['desc'])

//Result
[1,1,2,3,4,6,15]

Et je suis intéressé à le trier par ordre décroissant avec lodash, donc le résultat attendu devrait être:

var sortd = {b: 1, g: 1,c: 2, e: 3, d: 4, f: 6, a: 15}

J'ai essayé d'utiliser lodash orderBy mais cela donne un tableau contenant uniquement les valeurs triées.

var unsorted = {a: 15, b: 1,c: 2, d: 4, e: 3, f: 6, g: 1}


3 commentaires

Les objets n'ont pas d'ordre. vous devez utiliser un tableau si l'ordre est important


La réponse est non! Même si vous créez un objet avec des propriétés triées, il n'est pas garanti qu'ils s'afficheront dans le même ordre à l'avenir.


Allons! la commande est désormais standard. vient d'abord indexer les mêmes éléments dans l'ordre et le reste dans l'ordre d'insertion.


3 Réponses :


5
votes

Vous pouvez créer un nouvel objet avec les paires clé / valeur triées.

La norme actuelle ou l'ordre des propriétés:

  • triez d'abord l'index comme les clés, dans l'ordre
  • conserver toutes les autres clés dans l'ordre d'insertion

Pour un contrôle complet de l'ordre, prenez un tableau avec les clés et prenez-le comme accesseur trié pour les valeurs.

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
var unsorted = { a: 15, b: 1,c: 2, d: 4, e: 3, f: 6, g: 1 },
    sorted = _(unsorted)
        .toPairs()
        .orderBy(1, 'desc')
        .fromPairs()
        .value()
        
console.log(sorted);

Tri décroissant avec _.orderBy a> en utilisant le dernier paramètre pour une commande spécifique, au lieu de _.sortBy , qui permet uniquement de trier par ordre croissant.

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
var unsorted = { a: 15, b: 1,c: 2, d: 4, e: 3, f: 6, g: 1 },
    sorted = _(unsorted)
        .toPairs()
        .orderBy([1], ['desc'])
        .fromPairs()
        .value()
        
console.log(sorted);


1 commentaires

C'est exactement ce que je recherche. Je vous remercie. Cependant, comment puis-je trier par ordre croissant?



4
votes

JavaScript ne garantit pas l'ordre des clés dans un objet, c'est pourquoi lodash vous renvoie un tableau, car un objet avec des clés ordonnées n'est pas garanti. Consultez cette question SO .

Cependant, vous pouvez utiliser une Map , qui garantit l'ordre des clés.

Vous pouvez le faire avec du JavaScript pur:

p>

const unsorted = { a: 15, b: 1,c: 2, d: 4, e: 3, f: 6, g: 1 };

const sorted = new Map(Object.entries(unsorted).sort((a, b) => a[1] - b[1]));

for (const [key, val] of sorted) {
  console.log(key, val);
}

Vous avez plusieurs façons d'itérer le contenu de la carte résultante:

  • map.values ​​() : récupère le tableau de valeurs
  • map.entries () : récupère un tableau de [clé, valeur] paires
  • map.keys () : récupère un tableau de clés

Voir la documentation sur Map .


3 commentaires

Merci @jo_va, mais j'ai compris qu'un simple Object.entries (unsorted) .sort ((a, b) => a [1] - b [1]) fait la même chose sans le besoin de la boucle for-of.


Exactement, si vous voulez le tableau, comme indiqué dans ma réponse, j'enveloppe simplement ce résultat dans une carte si vous souhaitez accéder à vos valeurs par clés, comme vous le feriez avec un objet


Oh oui. Je comprends. Merci quand même.



1
votes

Ici, vous avez une autre approche ( sans lodash ). Fondamentalement, nous créons un tableau de type [[clé1, valeur1], [clé2, valeur2], ...] en utilisant Object.entries (non triés) , puis trions cela tableau (croissant / décroissant) comparant les valeurs , pour enfin reconstruire la structure d'objet que vous avez à l'origine, d'abord mapper les paires [clé, valeur] aux objets {clé : value} puis en assignant tous ces objets à un nouveau en utilisant Object.assign().

.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
var unsorted = {a: 15, b: 1,c: 2, d: 4, e: 3, f: 6, g: 1};

let sortedAsc = Object.entries(unsorted)
    .sort(([k1,v1], [k2,v2]) => v1 - v2)
    .map(([x,y]) => ({[x]:y}));
    
let sortedDesc = Object.entries(unsorted)
    .sort(([k1,v1], [k2,v2]) => v2 - v1)
    .map(([x,y]) => ({[x]:y}));

let objSortedAsc = Object.assign({}, ...sortedAsc);
let objSortedDesc = Object.assign({}, ...sortedDesc);

console.log("ASC: ", objSortedAsc, "DESC: ", objSortedDesc);


0 commentaires