Często znajduję się przy leniwej liście, kiedy chcę mieć wektor i odwrotnie. Czasami mam też wektor map, kiedy bardzo chciałem mieć zestaw map. Czy są jakieś funkcje pomocnicze, które pomogą mi w konwersji między tymi typami?
Nie zapominajmy, że zaufany stary into
pozwala ci wziąć wszystko, co jest w seq
stanie (lista, wektor, mapa, zestaw, posortowana-mapa) i pusty pojemnik, który chcesz wypełnić, i umieścić into
to.
(into [] '(1 2 3 4)) ==> [1 2 3 4] "have a lazy list and want a vector"
(into #{} [1 2 3 4]) ==> #{1 2 3 4} "have a vector and want a set"
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2} "have a set of vectors want a map"
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps"
into
to opakowanie wokół conj
, które jest podstawową abstrakcją do wstawiania nowych wpisów odpowiednio do kolekcji w oparciu o typ kolekcji. Zasada, która sprawia, że ten przepływ jest tak przyjemny, polega na tym, że Clojure jest zbudowany na abstrakcyjnych kompozycjach , w tym przypadku into
na szczycie conj
kolekcji i seq
.
Powyższe przykłady nadal dobrze komponowałyby się, gdyby odbiorca był przekazywany w czasie wykonywania: ponieważ bazowe abstrakcje ( seq
i conj
) są zaimplementowane dla wszystkich kolekcji (i wielu kolekcji Javy), więc wyższe abstrakcje nie muszą się martwić o wielu specjalnych przypadkach narożnych związanych z danymi.
into
użycieconj
, działanie(into '() some-seq)
da listę, która jest odwrotnością niektórych-seq, ponieważconj
wady na listy.into
wykorzystuje transjenty (dla większości typów sekwencyjnych) w celu uzyskania lepszych charakterystyk wydajności niż większość innych środków konwersji.vec
,set
i ogólnieinto
są Twoimi przyjaciółmi, aby łatwo „przekonwertować” na inny typ kolekcji.Jak chcesz przekształcić wektor map w mapę map? Potrzebujesz klucza, czy możesz użyć przykładowego wejścia / oczekiwanego wyjścia?
źródło
W przypadku wektorów istnieje
vec
funkcjauser=> (vec '(1 2 3)) [1 2 3]
Dla leniwych sekwencji jest
lazy-seq
funkcjauser=> (lazy-seq [1 2 3]) (1 2 3)
Do zamiany na zbiory jest
set
funkcjauser=> (set [{:a :b, :c :d} {:a :b} {:a :b}]) #{{:a :b} {:a :b, :c :d}}
źródło
lazy-seq
zamiast poseq
prostu dodaje bezużyteczne pośrednictwo. Jeśli naprawdę chcesz zwrócić coś niezerowego, nawet przed pustą kolekcją, to jestsequence
.lazy-seq
jest w pewnym sensie konstrukcją niskiego poziomu.Jeszcze jedna odpowiedź na konwersję z listy do mapy (ze względu na kompletność) - stąd :
(apply hash-map '(1 2 3 4)) ;=>{1 2, 3 4}
źródło
Aby przekonwertować wektor na listę, możesz również użyć
for
, na przykład:=> (for [i [1 2 3 4]] i) (1 2 3 4)
Jeśli nie chcesz manipulować danymi, po prostu użyj
seq
na wektorze:=> (seq [1 2 3]) (1 2 3)
źródło
for
możesz po prostu zrobić(map identity [1 2 3 4])
Nie ma potrzeby przekształcania wektora na listę. Clojure potraktuje wektor tak, jak traktuje listę - jako sekwencję - gdy sekwencja jest wymagana. Na przykład,
user=> (cons 0 [1 2 3]) (0 1 2 3)
Jeśli chcesz się upewnić, że wektor jest traktowany jako sekwencja, zawiń go w
seq
:user=> (conj [1 2 3] 0) ; treated as a vector [1 2 3 0] user=> (conj (seq [1 2 3]) 0) ; treated as a sequence (0 1 2 3)
Jeśli masz wektor map i potrzebujesz zestawu map, nie ma znaczenia, że wektor zawiera mapy. Po prostu konwertujesz wektor na zestaw jak zwykle:
user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}]) #{{:a 1, :b 2} {"four" 4, "three" 3}}
źródło