Ao iterar por meio do mapa retornado no código, retornado pela função de tópico, as chaves não aparecem em ordem.
Como posso colocar as chaves em ordem / classificar o mapa de modo que as chaves estejam em ordem e os valores correspondam?
Aqui está o código .
Respostas:
O blog Go: Mapas Go em ação tem uma explicação excelente.
Esta é minha versão modificada do código de exemplo: http://play.golang.org/p/dvqcGPYy3-
Resultado:
fonte
keys := make([]int, len(m))
e, em seguida, inserir por índice emkeys[i] = k
vez deappend
De acordo com a especificação Go , a ordem de iteração em um mapa é indefinida e pode variar entre as execuções do programa. Na prática, não só é indefinido, como também é aleatório intencionalmente. Isso porque costumava ser previsível, e os desenvolvedores da linguagem Go não queriam que as pessoas confiassem em um comportamento não especificado, então eles o randomizaram intencionalmente para que depender desse comportamento fosse impossível.
O que você terá que fazer, então, é puxar as chaves em uma fatia, classificá-las e, em seguida, percorrer a fatia assim:
fonte
Todas as respostas aqui agora contêm o antigo comportamento dos mapas. No Go 1.12+, você pode simplesmente imprimir um valor do mapa e ele será classificado por chave automaticamente. Isso foi adicionado porque permite o teste dos valores do mapa facilmente.
Leia mais aqui .
fonte
Se, como eu, você descobrir que deseja essencialmente o mesmo código de classificação em mais de um lugar, ou apenas deseja manter a complexidade do código baixa, pode abstrair a própria classificação para uma função separada, para a qual você passa a função que faz o trabalho real que você deseja (que seria diferente em cada local de chamada, é claro).
Dado um mapa com tipo de chave
K
e tipo de valorV
, representado como<K>
e<V>
abaixo, a função de classificação comum pode ser semelhante a este modelo Go-code (que Go versão 1 não suporta no estado em que se encontra):Em seguida, chame-o com o mapa de entrada e uma função (tomando
(k <K>, v <V>)
como seus argumentos de entrada) que é chamada sobre os elementos do mapa na ordem de chave classificada.Portanto, uma versão do código na resposta postada por Mingu pode ser semelhante a:
A
sortedMapIntString()
função pode ser reutilizada para qualquermap[int]string
(assumindo que a mesma ordem de classificação seja desejada), mantendo cada uso em apenas duas linhas de código.As desvantagens incluem:
Outros idiomas têm várias soluções:
<K>
e<V>
(para denotar os tipos de chave e valor) parece um pouco familiar, esse modelo de código não é muito diferente dos modelos C ++.range
um tipo de primeira classe que possa ser substituído por um personalizadoordered-range
(no lugar derange
no código original), acho que algumas outras linguagens fornecem iteradores que são poderosos o suficiente para realizar o mesmo coisa.fonte
Em resposta a James Craig Burley's resposta . Para fazer um design limpo e reutilizável, pode-se escolher uma abordagem mais orientada a objetos. Desta forma, os métodos podem ser associados com segurança aos tipos do mapa especificado. Para mim, essa abordagem parece mais limpa e organizada.
Exemplo:
Exemplo de playground estendido com vários tipos de mapa.
Nota importante
Em todos os casos, o mapa e a fatia classificada são desacoplados a partir do momento em que o
for
loop sobre o maparange
é concluído. O que significa que, se o mapa for modificado após a lógica de classificação, mas antes de usá-lo, você poderá ter problemas. (Não thread / Go rotina segura). Se houver uma alteração no acesso de gravação do mapa paralelo, você precisará usar um mutex em torno das gravações e dofor
loop classificado .fonte
Isso fornece a você o exemplo de código no mapa de classificação. Basicamente, isso é o que eles fornecem:
e isso é o que eu sugeriria usar em seu lugar :
O código completo pode ser encontrado neste Go Playground .
fonte