수색…


통사론

  • '()()
  • '(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 , countseq 함수를 지원합니다.

  • 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

모든 목록은 순서이지만 모든 순서가 목록이 아님을 기억하십시오. 목록은 peekpop 지원하고 일정 시간 내에 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

시퀀스가 유용하다는 또 다른 이유는 firstrest 의 특정 구현을 요구하지 않기 때문에 필요할 때만 요소가 실현되는 지연 시퀀스가 ​​허용되기 때문입니다.

시퀀스를 생성하는 표현식이 주어지면, lazy-seq 매크로에서 해당 표현식을 래핑하여 시퀀스와 같은 역할을하는 객체를 얻을 수 있지만, seq 함수로 요청할 때 실제로 해당 표현식 만 평가합니다. 어느 지점은 표현식의 결과를 캐시하고 firstrest 호출을 캐시 된 결과로 전달합니다.

유한 시퀀스의 경우, 지연 시퀀스는 대개 동등한 열망 시퀀스와 동일하게 작동합니다.

(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]"})


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow