Tenho dados em um arquivo de texto formatado assim:
1 2
3 4
5 6
7 8
9 0
Quero criar uma lista para cada coluna, assim:
((1 3 5 7 9) (2 4 6 8 0))
Na verdade, eu encontrei uma solução que funciona:
(defn make-lists []
(let [lines (clojure.string/split-lines (slurp "input"))]
(let [l1 (map #(parse-long (first (clojure.string/split % #" "))) lines)
l2 (map #(parse-long (nth (clojure.string/split % #" ") 3)) lines)]
(list l1 l2))))
No entanto, acho que há alguns problemas com essa solução. Não tenho certeza de como map
funciona por baixo dos panos, mas temo que isso resulte em duas iterações sobre a entrada quando, teoricamente, uma deveria ser suficiente.
Infelizmente, há mais de um espaço que separa os dois valores em cada linha nos dados de entrada. E clojure.string/split
produz um resultado para cada um deles. Portanto, tenho essa procura arbitrária nth 3
por l2 no meu código da qual gostaria de me livrar.
Eu apreciaria qualquer ideia de como melhorar esse código.
Em geral, você não deve se importar tanto com iterar mais de uma vez sobre algo. É comum, está tudo bem, considere otimizar apenas se você já provou que é um gargalo.
Sobre espaços - esse argumento
str/split
é uma expressão regular. Basta usar#" +"
em vez de#" "
.Com isso em mente, é assim que eu faria:
Só para esclarecer um pouco sobre a primeira resposta, eu gosto de espalhar os passos para começar. Na biblioteca tupelo, há macros
let-spy
elet-spy-pretty
que imprimem o resultado de cada passo:com resultado:
Gosto de usar
(str/trim ...)
no início do processo para me livrar de todos os espaços iniciais/finais (e novas linhas!) antes de analisar/segmentar a linha, analisar para int/float, etc. Também gosto de usarmapv
em vez demap
is, pois não é preguiçoso e sempre produz um resultado vetorial (mais fácil de cortar/colar em testes de unidade sem aspas).Depois que tudo estiver funcionando, basta substituir
let-spy-pretty
porlet
e formatar normalmente. Eu geralmente não me incomodo em condensar os passos individuais com->
ou algo assim, então fica mais óbvio para leitores subsequentes do código como a transformação acontece passo a passo (especialmente se eles precisarem modificar algo ou adicionar instruções de impressão de depuração).