Eu quero transformar um mapa de valores em outro mapa com as mesmas chaves, mas com uma função aplicada aos valores. Eu pensaria que havia uma função para fazer isso na API do clojure, mas não consegui encontrá-la.
Aqui está um exemplo de implementação do que estou procurando
(defn map-function-on-map-vals [m f]
(reduce (fn [altered-map [k v]] (assoc altered-map k (f v))) {} m))
(println (map-function-on-map-vals {:a "test" :b "testing"} #(.toUpperCase %)))
{:b TESTING, :a TEST}
Alguém sabe se map-function-on-map-vals
já existe? Eu acho que sim (provavelmente com um nome melhor também).
dictionary
clojure
map-function
Thomas
fonte
fonte
map
por algum motivo.Você pode usar o
clojure.algo.generic.functor/fmap
:fonte
org.clojure/algo.generic "0.1.0"
o exemplo agora deve ser o seguinte:(use '[clojure.algo.generic.functor :only (fmap)]) (fmap inc {:a 1 :b 3 :c 5})
fmap
ClojureScript?Aqui está uma maneira bastante típica de transformar um mapa.
zipmap
pega uma lista de chaves e uma lista de valores e "faz a coisa certa" produzindo um novo mapa de Clojure. Você também pode colocar asmap
teclas para alterá-las, ou ambas.ou envolvê-lo em sua função:
fonte
Retirado do livro de receitas de Clojure, há reduzido-kv:
fonte
Aqui está uma maneira bastante idiomática de fazer isso:
Exemplo:
fonte
map-map
,map-map-keys
, Emap-map-values
Não conheço nenhuma função existente no Clojure para isso, mas aqui está uma implementação dessa função
map-map-values
que você é livre para copiar. Ele vem com duas funções intimamente relacionadasmap-map
emap-map-keys
também estão ausentes na biblioteca padrão:Uso
Você pode ligar
map-map-values
assim:E as outras duas funções assim:
Implementações alternativas
Se você deseja apenas
map-map-keys
oumap-map-values
, sem amap-map
função mais geral , pode usar estas implementações, que não dependem demap-map
:Além disso, aqui está uma implementação alternativa
map-map
baseada emclojure.walk/walk
vez deinto
, se você preferir este fraseado:Versões paralelas -
pmap-map
, etc.Existem também versões paralelas dessas funções, se você precisar delas. Eles simplesmente usam em
pmap
vez demap
.fonte
Como sou um Clojure n00b, é possível que haja soluções muito mais elegantes. Aqui está o meu:
A função anon cria uma pequena lista de 2 de cada tecla e seu valor encontrado. O Mapcat executa essa função na sequência das chaves do mapa e concatena todo o trabalho em uma grande lista. "aplicar mapa de hash" cria um novo mapa a partir dessa sequência. O (% m) pode parecer um pouco estranho, é Clojure idiomático por aplicar uma chave a um mapa para procurar o valor associado.
Leitura altamente recomendada: The Clojure Cheat Sheet .
fonte
fonte
Eu gosto da sua
reduce
versão. Com uma variação muito pequena, ele também pode reter o tipo de estrutura de registros:O
{}
foi substituído porm
. Com essa alteração, os registros permanecem registros:Ao começar
{}
, o registro perde sua prontidão , que talvez você queira reter, se desejar os recursos de registro (representação de memória compacta, por exemplo).fonte
Estou me perguntando por que ninguém mencionou a biblioteca de espectros ainda. Ele foi escrito para facilitar a transformação desse tipo de código (e, ainda mais importante, o código escrito fácil de entender), apesar de ter um desempenho muito bom:
Escrever essa função no Clojure puro é simples, mas o código fica muito mais complicado quando você passa para um código altamente aninhado, composto de diferentes estruturas de dados. E é aí que entra o espectro .
Eu recomendo assistir este episódio na TV Clojure, que explica a motivação por trás e os detalhes do espectro .
fonte
O Clojure 1.7 ( lançado em 30 de junho de 2015) fornece uma solução elegante para isso com
update
:fonte