Lodash: comment faire un tri insensible à la casse sur une collection en utilisant orderBy?

87

J'ai vérifié cette réponse mais pour obtenir le même résultat, c'est-à-dire obtenir un tri insensible à la casse, je dois utiliser à la orderByplace de sortBycar cela donne la possibilité de spécifier l'ordre de tri .

Le seul moyen que j'ai trouvé pour y parvenir était de créer un tableau "central" cloné mappé en minuscules name:

const users = [
  { name: 'A', age: 48 },
  { name: 'B', age: 34 },
  { name: 'b', age: 40 },
  { name: 'a', age: 36 }
];

let lowerCaseUsers = _.clone(users);

lowerCaseUsers = lowerCaseUsers.map((user) => {
  user.name = user.name.toLowerCase();
  return user;
});

const sortedUsers = _.orderBy(lowerCaseUsers, ['name'], ['desc']);

console.log(sortedUsers);

Cela semble vraiment coûteux et ce sera même plus complexe avec plusieurs triages et noms de propriétés dynamiques.

Y a-t-il une meilleure idée?


Voici un Plunker: https://plnkr.co/edit/i1ywyxjFctuNfHtPTcgG

WhiteEleven
la source

Réponses:

188

La documentation précise que vous pouvez passer une fonction en tant que "iteratee":

[iteratees = [_. identity]] (Array [] | Function [] | Object [] | string []): Les itérations à trier.

Alors tu peux faire

const users = [
  { name: 'A', age: 48 },
  { name: 'B', age: 34 },
  { name: 'b', age: 40 },
  { name: 'a', age: 36 }
];

const sortedUsers = _.orderBy(users, [user => user.name.toLowerCase()], ['desc']);
console.log(sortedUsers);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

Félix Kling
la source
1
Cela peut échouer sur les anciens navigateurs.
vapeur le
14
Si vous voulez dire que cela générera une erreur de syntaxe dans le navigateur ne prenant pas en charge ES6, alors oui, bien sûr. Je laisserai la conversion de la fonction fléchée en une fonction "normale" (et consten var) comme exercice pour le lecteur.
Felix Kling
@TheCaptan: il n'y a aucune raison pour que ce ne soit pas le cas.
Felix Kling
2
J'essaye la question de @ TheCaptan avec ce qui suit, mais j'obtiens une erreur de compilation:const sortedUsers = _.orderBy(users, [user => user[propToSort].toLowerCase()], ['desc']);
im1dermike
1
@ im1dermike: vous voudrez probablement utiliser .toString()avant d'appeler en minuscules là-bas, en plus si vous voulez utiliser property.somethingpour propToSort et similaire, vous pouvez utiliser _.get(user, propToSort)(peut-être que cela aidera quelqu'un d'autre)
Soniku
10

Commande par plusieurs propriétés:

const users = [
  { name: 'A', age: 48 },
  { name: 'B', age: 34 },
  { name: 'b', age: 40 },
  { name: 'a', age: 36 }
]

const nameSorter = user => user.name.toLowerCase()
const ageSorter = 'age'

const sortedUsers = _.orderBy(users, [nameSorter, ageSorter], ['desc', 'asc'])
MaxineHu
la source
2

Vous pouvez combiner l'exemple de Felix Kling avec la fonction _.get pour trier par attributs imbriqués dynamiques:

const _ = require('lodash');

let test = [{ a: {b:'AA'}},{a: {b:'BB'} }, {a: {b: 'bb'}}, {a:{b:'aa'}}];

let attrPath = 'a.b';

_.orderBy(test, [item => _.get(item, attrPath).toLowerCase()]);
Agustí Sánchez
la source