No Clojure, quero combinar duas listas para fornecer uma lista de pares,
> (zip '(1 2 3) '(4 5 6))
((1 4) (2 5) (3 6))
Em Haskell ou Ruby, a função é chamada zip . Implementá-lo não é difícil, mas eu queria ter certeza de que não estava perdendo uma função no Core ou no Contrib.
Há um espaço para nome zip no Core, mas é descrito como fornecendo acesso à técnica funcional do Zipper, que não parece ser o que estou procurando.
Existe uma função equivalente para combinar 2 ou mais listas, dessa maneira, no Core?
Se não houver, é porque existe uma abordagem idiomática que torna a função desnecessária?
zip
função na biblioteca Tupelo: cloojure.github.io/doc/tupelo/tupelo.core.html#var-zipRespostas:
faz o que você quer:
Haskell precisa de uma coleção de
zipWith
(zipWith3
,zipWith4
...) funções, porque todos precisam ser de um determinado tipo ; em particular, o número de listas de entrada que eles aceitam precisa ser corrigido. (Azip
,zip2
,zip3
, ... família pode ser considerada como uma especialização dazipWith
família para o caso de uso comum de tupling).Por outro lado, Clojure e outros Lisps têm um bom suporte para funções variáveis de aridade;
map
é um deles e pode ser usado para "tupling" de maneira semelhante à de HaskellA maneira idiomática de criar uma "tupla" no Clojure é construir um vetor curto, conforme exibido acima.
(Apenas para completar, observe que o Haskell com algumas extensões básicas permite funções variáveis de aridade; no entanto, usá-las requer uma boa compreensão da linguagem, e o Haskell 98 baunilha provavelmente não as suporta, portanto, as funções de aridade fixa são preferíveis para a biblioteca padrão.)
fonte
zip
quando as coleções não têm o mesmo comprimento. Ruby continuará processando e fornecendonil
s para a coleção mais curta, enquanto Clojure interromperá o processamento assim que uma das coleções estiver esgotada.zip
comporta-se como o de Clojure amap
esse respeito.ou mais geralmente
fonte
fonte
para fornecer exatamente o que você queria, o mapeamento
list
nas duas listas fornecerá uma lista de listas como no seu exemplo. Eu acho que muitos clojurianos tenderiam a usar vetores para isso, embora funcione com qualquer coisa. e as entradas não precisam ser do mesmo tipo. O mapa cria seqs a partir deles e mapeia os seqs para que qualquer entrada seq'able funcione bem.fonte
A maneira integrada seria simplesmente a função 'intercalar':
fonte
(partition 2 (interleave [1 2 3 4][5 6 7 8]))
Existe uma função chamada zipmap, que pode ter o efeito semelhante (zipmap
(1 2 3)
(4 5 6)) A saída é como fluxos: {3 6, 2 5, 1 4}fonte
# (apply map list%) transpõe uma matriz como a função zip * do Python. Como uma definição de macro:
user => (defmacro py-zip [lst] `(aplica lista de mapas ~ lst))
# 'usuário / py-zip
user => (py-zip '((1 2 3 4) (9 9 9 9) (5 6 7 8)))
((1 9 5) (2 9 6) (3 9 7) (4 9 8))
user => (py-zip '((1 9 5) (2 9 6) (3 9 7) (4 9 8)))
((1 2 3 4) (9 9 9 9) (5 6 7 8))
fonte