수색…
통사론
-
'()
→()
-
'(1 2 3 4 5)
→(1 2 3 4 5)
-
'(1 foo 2 bar 3)
→(1 'foo 2 'bar 3)
-
(
list
1 2 3 4 5)
→(1 2 3 4 5)
-
(
list*
[1 2 3 4 5])
→(1 2 3 4 5)
-
[]
→[]
-
[1 2 3 4 5]
→[1 2 3 4 5]
-
(
vector
1 2 3 4 5)
→[1 2 3 4 5]
-
(
vec
'(1 2 3 4 5))
→[1 2 3 4 5]
-
{}
=>{}
-
{:keyA 1 :keyB 2}
→{:keyA 1 :keyB 2}
-
{:keyA 1, :keyB 2}
→{:keyA 1 :keyB 2}
-
(
hash-map
:keyA 1 :keyB 2)
→{:keyA 1 :keyB 2}
-
(
sorted-map
5 "five" 1 "one")
→{1 "one" 5 "five"}
(시퀀스로 사용될 때 엔트리는 키로 정렬 됨) -
#{}
→#{}
-
#{1 2 3 4 5}
→#{4 3 2 5 1}
(정렬되지 않음) -
(
hash-set
1 2 3 4 5)
→#{2 5 4 1 3}
(정렬되지 않음) -
(
sorted-set
2 5 4 3 1)
→#{1 2 3 4 5}
컬렉션
내장 된 모든 Clojure 컬렉션은 변경 불가능하고 이질적이며, 리터럴 구문을 사용하고 conj
, count
및 seq
함수를 지원합니다.
-
conj
는 "추가됨"항목이있는 기존 컬렉션과 동일한 새 컬렉션을 "상수"또는 로그 시간으로 반환합니다. 이것이 정확히 무엇을 의미하는지는 컬렉션에 달려 있습니다. -
count
는 일정 기간 동안 컬렉션의 항목count
반환합니다. -
seq
는 빈 콜렉션에 대해nil
또는 비어 있지 않은 콜렉션에 대한 항목 시퀀스를 일정 시간에 반환합니다.
기울기
목록은 괄호로 표시됩니다.
()
;;=> ()
Clojure 목록은 단일 연결 목록 입니다. conj
가장 효율적인 위치에 컬렉션에 새로운 요소를 "conjoins". 목록은 시작 부분에 있습니다.
(conj () :foo)
;;=> (:foo)
(conj (conj () :bar) :foo)
;;=> (:foo :bar)
다른 콜렉션과 달리, 비어 있지 않은리스트는 평가할 때 특수 폼, 매크로 또는 함수에 대한 호출로 평가됩니다. 따라서 (:foo)
는 다음과 같은 내용을 포함하는리스트의 리터럴 표현입니다 :foo
를 유일한 항목으로 포함하고 REPL에서 (:foo)
를 평가하면 nullary 함수 로 키워드를 호출 할 수 없으므로 IllegalArgumentException
이 발생 합니다 .
(:foo)
;; java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :foo
Clojure가 비어 있지 않은 목록을 평가하지 못하도록하려면 다음과 같이 quote
할 수 있습니다.
'(:foo)
;;=> (:foo)
'(:foo :bar)
;;=> (:foo :bar)
불행히도 요소가 평가되지 않게됩니다.
(+ 1 1)
;;=> 2
'(1 (+ 1 1) 3)
;;=> (1 (+ 1 1) 3)
이런 이유 때문에 일반적으로 모든 인수를 평가하고 그 결과를 사용하여 목록을 구성하는 가변 함수 인 list
를 사용하려고합니다.
(list)
;;=> ()
(list :foo)
;;=> (:foo)
(list :foo :bar)
;;=> (:foo :bar)
(list 1 (+ 1 1) 3)
;;=> (1 2 3)
count
는 상수 시간에 항목 count
반환합니다.
(count ())
;;=> 0
(count (conj () :foo))
;;=> 1
(count '(:foo :bar))
;;=> 2
목록을 사용하여 list?
이 있는지 여부를 테스트 할 수 list?
술부:
(list? ())
;;=> true
(list? '(:foo :bar))
;;=> true
(list? nil)
;;=> false
(list? 42)
;;=> false
(list? :foo)
;;=> false
peek
사용하여 목록의 첫 번째 요소를 가져올 수 있습니다.
(peek ())
;;=> nil
(peek '(:foo))
;;=> :foo
(peek '(:foo :bar))
;;=> :foo
pop
사용하는 첫 번째 요소없이 새 목록을 얻을 수 있습니다.
(pop '(:foo))
;;=> ()
(pop '(:foo :bar))
;;=> (:bar)
빈리스트를 pop
하려고하면 (자), IllegalStateException
가 발생 IllegalStateException
.
(pop ())
;; java.lang.IllegalStateException: Can't pop empty list
마지막으로 모든 목록은 시퀀스이므로 다른 순서로 수행 할 수있는 목록으로 모든 작업을 수행 할 수 있습니다. 사실, 빈 목록을 제외하고 목록에서 seq
을 호출하면 똑같은 객체가 반환됩니다.
(seq ())
;;=> nil
(seq '(:foo))
;;=> (:foo)
(seq '(:foo :bar))
;;=> (:foo :bar)
(let [x '(:foo :bar)]
(identical? x (seq x)))
;;=> true
시퀀스
시퀀스는 목록과 매우 흡사합니다. 즉, first
요소 또는 rest
요소를 일정 시간 내에 제공 할 수있는 불변 개체입니다. 당신은 또한 수 있습니다 cons
처음에 충실하기 위해 기존 순서 및 항목에서 새 순서를 truct.
seq?
사용하여 무언가가 시퀀스인지 테스트 할 수 seq?
술부:
(seq? nil)
;;=> false
(seq? 42)
;;=> false
(seq? :foo)
;;=> false
이미 알고 있듯이 목록은 시퀀스입니다.
(seq? ())
;;=> true
(seq? '(:foo :bar))
;;=> true
당신이 호출하여 얻을 아무것도 seq
또는 rseq
또는 keys
또는 vals
비 비어 컬렉션도 순서입니다 :
(seq? (seq ()))
;;=> false
(seq? (seq '(:foo :bar)))
;;=> true
(seq? (seq []))
;;=> false
(seq? (seq [:foo :bar]))
;;=> true
(seq? (rseq []))
;;=> false
(seq? (rseq [:foo :bar]))
;;=> true
(seq? (seq {}))
;;=> false
(seq? (seq {:foo :bar :baz :qux}))
;;=> true
(seq? (keys {}))
;;=> false
(seq? (keys {:foo :bar :baz :qux}))
;;=> true
(seq? (vals {}))
;;=> false
(seq? (vals {:foo :bar :baz :qux}))
;;=> true
(seq? (seq #{}))
;;=> false
(seq? (seq #{:foo :bar}))
;;=> true
모든 목록은 순서이지만 모든 순서가 목록이 아님을 기억하십시오. 목록은 peek
과 pop
지원하고 일정 시간 내에 count
하는 반면, 일반적으로 시퀀스는 그러한 기능을 지원할 필요가 없습니다. Clojure의 스택 인터페이스를 지원하지 않는 시퀀스에서 peek
또는 pop
을 호출하려고하면 ClassCastException
.
(peek (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack
(pop (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack
(peek (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack
(pop (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack
(peek (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack
(pop (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack
상수 시간에 count
를 구현하지 않는 시퀀스에서 count
를 호출하면 오류가 발생하지 않습니다. 대신 Clojure는 끝까지 도달 할 때까지 전체 시퀀스를 트래버스하고, 통과 한 요소의 수를 반환합니다. 즉, 일반 시퀀스의 경우 count
가 선형이 아닌 일정한 시간입니다. count
사용하여 일정 시간 count
를 지원하는지 여부를 테스트 할 수 있습니다 counted?
술부:
(counted? '(:foo :bar))
;;=> true
(counted? (seq '(:foo :bar)))
;;=> true
(counted? [:foo :bar])
;;=> true
(counted? (seq [:foo :bar]))
;;=> true
(counted? {:foo :bar :baz :qux})
;;=> true
(counted? (seq {:foo :bar :baz :qux}))
;;=> true
(counted? #{:foo :bar})
;;=> true
(counted? (seq #{:foo :bar}))
;;=> false
위에서 언급 한 바와 같이, 당신이 사용할 수있는 first
시퀀스의 첫 번째 요소를 얻을 수 있습니다. first
인수에 seq
를 호출하므로 실제 시퀀스가 아닌 "seqable"에 사용할 수 있습니다.
(first nil)
;;=> nil
(first '(:foo))
;;=> :foo
(first '(:foo :bar))
;;=> :foo
(first [:foo])
;;=> :foo
(first [:foo :bar])
;;=> :foo
(first {:foo :bar})
;;=> [:foo :bar]
(first #{:foo})
;;=> :foo
또한 위에서 언급했듯이, rest
를 사용하여 기존 시퀀스의 첫 번째 요소를 제외하고 모두를 포함하는 시퀀스를 가져올 수 있습니다. first
, 인수에 대해 seq
를 호출합니다. 그러나 결과에 seq
를 호출하지 않습니다 ! 즉, 두 개 미만의 항목을 포함하는 시퀀스에서 rest
를 호출하면 nil
대신 back ()
이 반환됩니다.
(rest nil)
;;=> ()
(rest '(:foo))
;;=> ()
(rest '(:foo :bar))
;;=> (:bar)
(rest [:foo])
;;=> ()
(rest [:foo :bar])
;;=> (:bar)
(rest {:foo :bar})
;;=> ()
(rest #{:foo})
;;=> ()
시퀀스에 더 이상 요소가 없을 때 nil
되돌리려면 rest
대신 next
를 사용할 수 있습니다.
(next nil)
;;=> nil
(next '(:foo))
;;=> nil
(next [:foo])
;;=> nil
cons
함수를 사용하여 first에 대한 first
번째 인수와 rest
대한 두 번째 인수를 반환하는 새 시퀀스를 만들 수 있습니다.
(cons :foo nil)
;;=> (:foo)
(cons :foo (cons :bar nil))
;;=> (:foo :bar)
Clojure는 시퀀스 처리를위한 많은 함수를 가진 대규모 시퀀스 라이브러리 를 제공합니다. 이 라이브러리의 중요한 점은 목록이 아닌 "seqable"과 함께 작동한다는 것입니다. 그래서 시퀀스의 개념이 매우 유용합니다. reduce
와 같은 단일 함수가 모든 컬렉션에서 완벽하게 작동한다는 것을 의미합니다.
(reduce + '(1 2 3))
;;=> 6
(reduce + [1 2 3])
;;=> 6
(reduce + #{1 2 3})
;;=> 6
시퀀스가 유용하다는 또 다른 이유는 first
와 rest
의 특정 구현을 요구하지 않기 때문에 필요할 때만 요소가 실현되는 지연 시퀀스가 허용되기 때문입니다.
시퀀스를 생성하는 표현식이 주어지면, lazy-seq
매크로에서 해당 표현식을 래핑하여 시퀀스와 같은 역할을하는 객체를 얻을 수 있지만, seq
함수로 요청할 때 실제로 해당 표현식 만 평가합니다. 어느 지점은 표현식의 결과를 캐시하고 first
및 rest
호출을 캐시 된 결과로 전달합니다.
유한 시퀀스의 경우, 지연 시퀀스는 대개 동등한 열망 시퀀스와 동일하게 작동합니다.
(seq [:foo :bar])
;;=> (:foo :bar)
(lazy-seq [:foo :bar])
;;=> (:foo :bar)
그러나 그 차이는 무한 시퀀스에서 분명해진다.
(defn eager-fibonacci [a b]
(cons a (eager-fibonacci b (+' a b))))
(defn lazy-fibonacci [a b]
(lazy-seq (cons a (lazy-fibonacci b (+' a b)))))
(take 10 (eager-fibonacci 0 1))
;; java.lang.StackOverflowError:
(take 10 (lazy-fibonacci 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)
벡터
벡터는 대괄호로 표시됩니다.
[]
;;=> []
[:foo]
;;=> [:foo]
[:foo :bar]
;;=> [:foo :bar]
[1 (+ 1 1) 3]
;;=> [1 2 3]
리터럴 구문을 사용하는 경우 vector
함수를 사용하여 vector
를 구성 할 수도 있습니다.
(vector)
;;=> []
(vector :foo)
;;=> [:foo]
(vector :foo :bar)
;;=> [:foo :bar]
(vector 1 (+ 1 1) 3)
;;=> [1 2 3]
벡터를 사용하여 무언가가 벡터인지 테스트 할 수 vector?
술부:
(vector? [])
;;=> true
(vector? [:foo :bar])
;;=> true
(vector? nil)
;;=> false
(vector? 42)
;;=> false
(vector? :foo)
;;=> false
conj
는 벡터의 끝에 요소를 추가합니다.
(conj [] :foo)
;;=> [:foo]
(conj (conj [] :foo) :bar)
;;=> [:foo :bar]
(conj [] :foo :bar)
;;=> [:foo :bar]
count
는 상수 시간에 항목 count
반환합니다.
(count [])
;;=> 0
(count (conj [] :foo))
;;=> 1
(count [:foo :bar])
;;=> 2
peek
사용하여 벡터의 마지막 요소를 얻을 수 있습니다.
(peek [])
;;=> nil
(peek [:foo])
;;=> :foo
(peek [:foo :bar])
;;=> :bar
pop
사용하여 마지막 요소가없는 새 벡터를 얻을 수 있습니다.
(pop [:foo])
;;=> []
(pop [:foo :bar])
;;=> [:foo]
빈 벡터를 팝하려고하면 IllegalStateException
.
(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector
목록과 달리 벡터는 색인이 생성됩니다. 다음을 사용하여 "상수"시간에 인덱스 벡터의 요소를 얻을 수 있습니다 get
:
(get [:foo :bar] 0)
;;=> :foo
(get [:foo :bar] 1)
;;=> :bar
(get [:foo :bar] -1)
;;=> nil
(get [:foo :bar] 2)
;;=> nil
또한 벡터 자체는 인덱스를 가져 와서 해당 인덱스에서 요소를 반환하는 함수입니다.
([:foo :bar] 0)
;;=> :foo
([:foo :bar] 1)
;;=> :bar
그러나 잘못된 인덱스가있는 벡터를 호출하면 nil
대신 IndexOutOfBoundsException
합니다.
([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:
([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:
assoc
사용하여 특정 인덱스에서 다른 값을 가진 새 벡터를 얻을 수 있습니다.
(assoc [:foo :bar] 0 42)
;;=> [42 :bar]
(assoc [:foo :bar] 1 42)
;;=> [:foo 42]
벡터의 count
와 동일한 인덱스를 전달하면 Clojure는 conj
사용하는 것처럼 요소를 추가합니다. 그러나 음수이거나 count
보다 큰 인덱스를 전달하면 IndexOutOfBoundsException
.
(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]
(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:
(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:
seq
사용하여 벡터의 항목 시퀀스를 가져올 수 있습니다.
(seq [])
;;=> nil
(seq [:foo])
;;=> (:foo)
(seq [:foo :bar])
;;=> (:foo :bar)
벡터가 인덱싱되므로 rseq
사용하여 벡터 항목의 역순으로 된 시퀀스를 얻을 수도 있습니다.
(rseq [])
;;=> nil
(rseq [:foo])
;;=> (:foo)
(rseq [:foo :bar])
;;=> (:bar :foo)
모든 목록은 시퀀스이지만 시퀀스는 목록과 동일한 방식으로 표시되지만 모든 시퀀스가 목록이 아닙니다!
'(:foo :bar)
;;=> (:foo :bar)
(seq [:foo :bar])
;;=> (:foo :bar)
(list? '(:foo :bar))
;;=> true
(list? (seq [:foo :bar]))
;;=> false
(list? (rseq [:foo :bar]))
;;=> false
세트
지도와 마찬가지로 세트는 연관적이고 순서가 없습니다. 키와 값의 매핑을 포함하는 맵과는 달리, 세트는 기본적으로 키에서 자체로 매핑됩니다.
집합은 중괄호 (octetorpe)가 앞에 오는 중괄호로 표시됩니다.
#{}
;;=> #{}
#{:foo}
;;=> #{:foo}
#{:foo :bar}
;;=> #{:bar :foo}
맵과 마찬가지로, 리터럴 집합에 요소가 나타나는 순서는 중요하지 않습니다.
(= #{:foo :bar} #{:bar :foo})
;;=> true
집합을 사용하여 무언가가 집합인지 여부를 테스트 할 수 set?
술부:
(set? #{})
;;=> true
(set? #{:foo})
;;=> true
(set? #{:foo :bar})
;;=> true
(set? nil)
;;=> false
(set? 42)
;;=> false
(set? :foo)
;;=> false
contains를 사용하여 "상수"시간에지도에 주어진 항목이 있는지 여부를 테스트 할 수 contains?
술부:
(contains? #{} :foo)
;;=> false
(contains? #{:foo} :foo)
;;=> true
(contains? #{:foo} :bar)
;;=> false
(contains? #{} nil)
;;=> false
(contains? #{nil} nil)
;;=> true
또한 집합 자체는 요소를 취하여 그 요소가 집합에 있으면 반환하거나 그렇지 않으면 nil
반환하는 함수입니다.
(#{} :foo)
;;=> nil
(#{:foo} :foo)
;;=> :foo
(#{:foo} :bar)
;;=> nil
(#{} nil)
;;=> nil
(#{nil} nil)
;;=> nil
conj
를 사용하여 기존 세트의 모든 요소와 하나의 추가 항목을 갖는 세트를 얻을 수 있습니다.
(conj #{} :foo)
;;=> #{:foo}
(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}
(conj #{:foo} :foo)
;;=> #{:foo}
당신은 disj
를 사용하여 하나의 항목을 뺀 기존 세트의 모든 요소를 가진 세트를 얻을 수 있습니다 :
(disj #{} :foo)
;;=> #{}
(disj #{:foo} :foo)
;;=> #{}
(disj #{:foo} :bar)
;;=> #{:foo}
(disj #{:foo :bar} :foo)
;;=> #{:bar}
(disj #{:foo :bar} :bar)
;;=> #{:foo}
count
는 일정 시간 동안 요소의 수를 반환합니다.
(count #{})
;;=> 0
(count (conj #{} :foo))
;;=> 1
(count #{:foo :bar})
;;=> 2
seq
사용하여 집합의 모든 요소 시퀀스를 얻을 수 있습니다.
(seq #{})
;;=> nil
(seq #{:foo})
;;=> (:foo)
(seq #{:foo :bar})
;;=> (:bar :foo)
지도
순차적 데이터 구조 인 목록과 순차적이고 결합적인 벡터와 달리지도는 독점적으로 연관 데이터 구조입니다. 맵은 키와 값의 맵핑 세트로 구성됩니다. 모든 키는 고유하므로 맵은 키에서 값까지 "상수"시간 조회를 지원합니다.
지도는 중괄호로 표시됩니다.
{}
;;=> {}
{:foo :bar}
;;=> {:foo :bar}
{:foo :bar :baz :qux}
;;=> {:foo :bar, :baz :qux}
두 요소의 각 쌍은 키 - 값 쌍입니다. 예를 들어 위의 첫 번째 맵에는 매핑이 없습니다. 두 번째는 키 :foo
에서 값 :bar
까지 하나의 매핑을 갖습니다. 세 번째는 두 개의 매핑을 가지고 있는데 하나는 키에서 :foo
는 값 :bar
, 다른 하나는 키 :baz
에서 값 :qux
합니다. 지도는 본질적으로 순서가 지정되지 않으므로 매핑이 나타나는 순서는 중요하지 않습니다.
(= {:foo :bar :baz :qux}
{:baz :qux :foo :bar})
;;=> true
지도를 사용하여 무언가가지도인지 테스트 할 수 map?
술부:
(map? {})
;;=> true
(map? {:foo :bar})
;;=> true
(map? {:foo :bar :baz :qux})
;;=> true
(map? nil)
;;=> false
(map? 42)
;;=> false
(map? :foo)
;;=> false
contains를 사용하여 "일정한"시간에 주어진 키 가지도에 포함되어 있는지 테스트 할 수 contains?
술부:
(contains? {:foo :bar :baz :qux} 42)
;;=> false
(contains? {:foo :bar :baz :qux} :foo)
;;=> true
(contains? {:foo :bar :baz :qux} :bar)
;;=> false
(contains? {:foo :bar :baz :qux} :baz)
;;=> true
(contains? {:foo :bar :baz :qux} :qux)
;;=> false
(contains? {:foo nil} :foo)
;;=> true
(contains? {:foo nil} :bar)
;;=> false
당신은 키 사용과 관련된 값을 얻을 수 있습니다 get
:
(get {:foo :bar :baz :qux} 42)
;;=> nil
(get {:foo :bar :baz :qux} :foo)
;;=> :bar
(get {:foo :bar :baz :qux} :bar)
;;=> nil
(get {:foo :bar :baz :qux} :baz)
;;=> :qux
(get {:foo :bar :baz :qux} :qux)
;;=> nil
(get {:foo nil} :foo)
;;=> nil
(get {:foo nil} :bar)
;;=> nil
또한지도 자체는 키를 가져 와서 해당 키와 관련된 값을 반환하는 함수입니다.
({:foo :bar :baz :qux} 42)
;;=> nil
({:foo :bar :baz :qux} :foo)
;;=> :bar
({:foo :bar :baz :qux} :bar)
;;=> nil
({:foo :bar :baz :qux} :baz)
;;=> :qux
({:foo :bar :baz :qux} :qux)
;;=> nil
({:foo nil} :foo)
;;=> nil
({:foo nil} :bar)
;;=> nil
find
사용하여 두 요소 벡터로 전체지도 항목 (키와 값을 함께 표시)을 얻을 수 있습니다.
(find {:foo :bar :baz :qux} 42)
;;=> nil
(find {:foo :bar :baz :qux} :foo)
;;=> [:foo :bar]
(find {:foo :bar :baz :qux} :bar)
;;=> nil
(find {:foo :bar :baz :qux} :baz)
;;=> [:baz :qux]
(find {:foo :bar :baz :qux} :qux)
;;=> nil
(find {:foo nil} :foo)
;;=> [:foo nil]
(find {:foo nil} :bar)
;;=> nil
key
또는 val
사용하여 맵 항목에서 키 또는 값을 추출 할 수 있습니다.
(key (find {:foo :bar} :foo))
;;=> :foo
(val (find {:foo :bar} :foo))
;;=> :bar
모든 Clojure 맵 항목이 벡터이지만 모든 벡터가 맵 항목이되는 것은 아닙니다. 지도 항목이 아닌 다른 항목에서 key
또는 val
을 호출하려고하면 ClassCastException
.
(key [:foo :bar])
;; java.lang.ClassCastException:
(val [:foo :bar])
;; java.lang.ClassCastException:
map-entry?
사용하여 무언가가지도 항목인지 테스트 할 수 map-entry?
술부:
(map-entry? (find {:foo :bar} :foo))
;;=> true
(map-entry? [:foo :bar])
;;=> false
assoc
을 사용하여 하나의 매핑을 추가하거나 변경하면서 기존지도와 동일한 키 - 값 쌍을 모두 갖는지도를 얻을 수 있습니다.
(assoc {} :foo :bar)
;;=> {:foo :bar}
(assoc (assoc {} :foo :bar) :baz :qux)
;;=> {:foo :bar, :baz :qux}
(assoc {:baz :qux} :foo :bar)
;;=> {:baz :qux, :foo :bar}
(assoc {:foo :bar :baz :qux} :foo 42)
;;=> {:foo 42, :baz :qux}
(assoc {:foo :bar :baz :qux} :baz 42)
;;=> {:foo :bar, :baz 42}
dissoc
을 사용 dissoc
기존지도와 동일한 키 - 값 쌍이 모두 포함 dissoc
를 가져올 수 있으며 하나의 매핑 만 제거 할 수 있습니다.
(dissoc {:foo :bar :baz :qux} 42)
;;=> {:foo :bar :baz :qux}
(dissoc {:foo :bar :baz :qux} :foo)
;;=> {:baz :qux}
(dissoc {:foo :bar :baz :qux} :bar)
;;=> {:foo :bar :baz :qux}
(dissoc {:foo :bar :baz :qux} :baz)
;;=> {:foo :bar}
(dissoc {:foo :bar :baz :qux} :qux)
;;=> {:foo :bar :baz :qux}
(dissoc {:foo nil} :foo)
;;=> {}
count
는 상수 시간에 매핑 count
반환합니다.
(count {})
;;=> 0
(count (assoc {} :foo :bar))
;;=> 1
(count {:foo :bar :baz :qux})
;;=> 2
seq
사용하여 맵에서 모든 항목의 시퀀스를 얻을 수 있습니다.
(seq {})
;;=> nil
(seq {:foo :bar})
;;=> ([:foo :bar])
(seq {:foo :bar :baz :qux})
;;=> ([:foo :bar] [:baz :qux])
다시 말하지만 맵은 순서가 지정되지 않으므로 맵에서 seq
를 호출하여 얻은 시퀀스의 항목 순서는 정의되지 않습니다.
당신은 키 또는 사용하여지도에서 바로 값의 시퀀스 얻을 수있는 keys
또는 vals
각각을 :
(keys {})
;;=> nil
(keys {:foo :bar})
;;=> (:foo)
(keys {:foo :bar :baz :qux})
;;=> (:foo :baz)
(vals {})
;;=> nil
(vals {:foo :bar})
;;=> (:bar)
(vals {:foo :bar :baz :qux})
;;=> (:bar :qux)
Clojure 1.9는 키가 동일한 네임 스페이스를 공유하는 맵을보다 간결하게 표현하기위한 리터럴 구문을 추가합니다. 두 경우 모두 맵이 동일하다는 점에 유의하십시오 (맵은 기본 네임 스페이스를 "알지 못합니다"). 이는 구문상의 편의 일뿐입니다.
;; typical map syntax
(def p {:person/first"Darth" :person/last "Vader" :person/email "[email protected]"})
;; namespace map literal syntax
(def p #:person{:first "Darth" :last "Vader" :email "[email protected]"})