Lodash: como fazer uma classificação sem distinção entre maiúsculas e minúsculas em uma coleção usando orderBy?

87

Verifiquei esta resposta, mas para obter o mesmo resultado, ou seja, obter uma classificação sem distinção entre maiúsculas e minúsculas, preciso usar em orderByvez de, sortBypois fornece a capacidade de especificar a ordem de classificação .

A única maneira que encontrei de fazer isso foi criar uma matriz clonada "intermediária" mapeada para letras minúsculas 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);

Isso parece muito caro e será ainda mais complexo com várias classificações e nomes de propriedades dinâmicas.

Existe uma ideia melhor?


Aqui está um Plunker: https://plnkr.co/edit/i1ywyxjFctuNfHtPTcgG

WhiteEleven
fonte

Respostas:

188

A documentação especifica que você pode passar uma função como "iteratee":

[iteratees = [_. identity]] (Array [] | Função [] | Objeto [] | string []): Os iteratees para classificar.

Então você pode fazer

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>

Felix Kling
fonte
1
Isso pode falhar em navegadores mais antigos.
movido a vapor de
14
Se você quer dizer que isso gerará um erro de sintaxe no navegador que não suporta ES6, então sim, é claro. Vou deixar de converter a função de seta para uma função "normal" (e constpara var) como exercício para o leitor.
Felix Kling de
@TheCaptan: não há razão para que não deva.
Felix Kling
2
Estou tentando fazer a pergunta de @ TheCaptan com o seguinte, mas recebo um erro do compilador:const sortedUsers = _.orderBy(users, [user => user[propToSort].toLowerCase()], ['desc']);
im1dermike
1
@ im1dermike: você provavelmente deseja usar .toString()antes de chamar para letras minúsculas, além disso, se quiser usar property.somethingpara propToSort e semelhantes, você pode usar _.get(user, propToSort)(talvez isso ajude outra pessoa)
Soniku
10

Ordenação por propriedades múltiplas:

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
fonte
2

Você pode combinar o exemplo de Felix Kling com a função _.get para classificar por atributos aninhados dinâmicos:

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
fonte