Eu tenho uma matriz multidimensional. A matriz primária é uma matriz de
[publicationID][publication_name][ownderID][owner_name]
O que estou tentando fazer é classificar a matriz por owner_name
e depois publication_name
. Eu sei em JavaScript que você tem Array.sort()
, em que você pode colocar uma função personalizada, no meu caso eu tenho:
function mysortfunction(a, b) {
var x = a[3].toLowerCase();
var y = b[3].toLowerCase();
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}
Isso é bom apenas para classificar em uma coluna, a saber owner_name, mas como modificá-lo para classificar owner_name
então publication_name
?
javascript
algorithm
sorting
flavour404
fonte
fonte
[[A, 10], [J, 15], [A, 5], [J, 5]] => [[A, 10], [A, 5], [J, 15], [J, 5]]
Eu acho que o que você está procurando é thenBy.js: https://github.com/Teun/thenBy.js
Ele permite que você use o padrão Array.sort, mas com
firstBy().thenBy().thenBy()
estilo.Um exemplo pode ser visto aqui .
fonte
thenBy
é chamado, todos os itens da matriz são repetidos novamente.Uma boa maneira de classificar em muitos campos que são seqüências de caracteres é usar
toLocaleCompare
o operador booleano||
.Algo como:
Se você deseja classificar em mais campos, basta encadear a declaração de retorno com mais operadores booleanos.
fonte
.reduce()
.localCompare()
retorna -1, 0, 1, então não acho que sua solução funcionará como o || é bom para booleanossortItems = (a, b) => (a.distance - b.distance) || (a.name - b.name);
e funciona como um encanto para minhas necessidades não exigentes.(a.name - b.name)
menos que seja necessário. A criação de variáveis primeiro faz um trabalho extra, mesmo que não seja necessário.Deparei com a necessidade de fazer ordenações de objetos asc e desc misturados no estilo SQL por chaves.
A solução da kennebec acima me ajudou a chegar a isso:
uso da amostra:
produz o seguinte:
(usando uma função de impressão daqui )
aqui está um exemplo de jsbin .
edit: limpo e postado como mksort.js no github .
fonte
Isso é útil para tipos alfa de todos os tamanhos. Passe os índices pelos quais você deseja classificar, em ordem, como argumentos.
fonte
Sugiro usar um comparador incorporado e encadear a ordem de classificação desejada com lógica ou
||
.Exemplo de trabalho:
fonte
Você pode concatenar as 2 variáveis em uma chave de classificação e usá-la para sua comparação.
fonte
Eu encontrei multisotr . É uma biblioteca simples, poderosa e pequena para classificação múltipla. Eu precisava classificar uma matriz de objetos com critérios de classificação dinâmica:
Essa biblioteca é mais poderosa, esse foi o meu caso. Tente.
fonte
Eu estava trabalhando
ng-grid
e precisava fazer a classificação de várias colunas em uma matriz de registros retornados de uma API, então criei essa função bacana e dinâmica de multi-classificação.Primeiro,
ng-grid
dispara um "evento" para "ngGridSorted" e passa essa estrutura de volta, descrevendo a classificação:Então, eu criei uma função que gerará dinamicamente uma função de classificação com base no
sortData
mostrado acima ( Não se assuste com a barra de rolagem! Tem apenas cerca de 50 linhas! Além disso, desculpe-me pelo slop. Impedia uma horizontal barra de rolagem! ):Em seguida, classifico os resultados da minha API (
results
) da seguinte forma:Espero que outra pessoa goste desta solução tanto quanto eu! Obrigado!
fonte
Tente o seguinte:
Mostrar snippet de código
Suponho que seus dados na matriz
let t = [ [publicationID, publication_name, ownderID, owner_name ], ... ]
onde índice de owner_name = 3 e publicação_name = 1.fonte
Método de adição de string
Você pode classificar por vários valores simplesmente anexando os valores a uma sequência e comparando-as. É útil adicionar um caractere de chave dividida para impedir o escoamento de uma chave para a seguinte.
Exemplo
fonte
fonte
Eu tive um problema semelhante ao exibir blocos de pool de memória a partir da saída de alguma composição virtual de funções h do DOM. Basicamente, enfrentei o mesmo problema ao classificar dados com vários critérios, como resultados de pontuação de jogadores de todo o mundo.
Percebi que a classificação com vários critérios é:
E se você não se importa, você pode falhar rapidamente em um inferno de aninhar-se ... como promessas de retorno de chamada ...
E se escrevermos uma função "predicado" para decidir se parte da alternativa está sendo usada? O predicado é simplesmente:
Agora, depois de escrever seus testes de classificação (porCountrySize, porAge, porGameType, porScore, porLevel ...) o que for necessário, você pode ponderar seus testes (1 = asc, -1 = desc, 0 = desativar), coloque-os em uma matriz e aplique uma função redutora 'decidir' da seguinte maneira:
E pronto! Cabe a você definir seus próprios critérios / pesos / pedidos ... mas você entendeu. Espero que isto ajude !
EDIT: * verifique se há uma ordem de classificação total em cada coluna * esteja ciente de não ter dependências entre as ordens das colunas e nenhuma dependência circular
se não, a classificação pode ser instável!
fonte
Minha própria biblioteca para trabalhar com iteráveis do ES6 (blinq) permite (entre outras coisas) a fácil classificação em vários níveis
fonte
Origem do GitHub
fonte
Acabei de publicar para o npm uma micro-biblioteca chamada sort-helper ( fonte no github ) . A idéia é importar o auxiliar
by
para criar a função de comparação para osort
método array através da sintaxeitems.sort(by(column, ...otherColumns))
, com várias maneiras de expressar as colunas para classificar por:persons.sort(by('lastName', 'firstName'))
,dates.sort(by(x => x.toISOString()))
,[3, 2, 4, 1].sort(by(desc(n => n)))
→[3, 2, 1, 0]
,['B', 'D', 'c', 'a'].sort(by(ignoreCase(x => x))).join('')
→'aBcD'
.É semelhante ao bom então mencionado por esta resposta, mas com as seguintes diferenças que podem ser mais do gosto de alguns:
thenBy
API fluente) ,fonte