수색…


통사론

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


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