#vector #clojure
#вектор #clojure
Вопрос:
> (conj [0] 1 2 3)
[0 1 2 3]
> (conj {:a "ei"} {:b "bi"})
{:b "bi", :a "ei"}
>
Смотрите, когда он воздействует на вектор, он помещает 1,2,3 в его конец.
В то время как он помещает: b «bi» перед: парой map k-v
Почему это так?
Спасибо
Ответ №1:
Как и во многих реализациях хешированных карт, хешированные карты Clojure не сортируют свои записи, не сохраняют порядок, в котором они были вставлены. Это позволяет повысить производительность.
Обратите внимание, что conj также не имеет общей семантики упорядочения (он имеет семантику упорядочения для некоторых конкретных типов, таких как векторы).
Комментарии:
1. Conj имеет семантику для каждого конкретного типа. Другими словами, это полиморфная функция.
2. sorted-map — это карта clojure, которая сортирует свои записи по ключу.
3. Также обратите внимание, что этот полиморфизм не возникает из ниоткуда: это не цель упорядочивания хэш-карты. Его цель — получить доступ из значения, имеющего другое значение, т.е. Для выполнения операций «объединения». Порядок so не имеет значения. кроме того, существуют векторы или отсортированные карты
4. @Mars вот почему я специально написал «хешированные карты», а не карты (просто повторно используя терминологию на clojure.org ).
Ответ №2:
Вам не нужно заходить так далеко, как карты, чтобы получить непоследовательное поведение от conj
:
(conj [1] 2) ; [1 2]
(conj (list 1) 2) ; (2 1)
Хэш-карты не имеют определенного порядка. Но для любой карты,
- количество
seq
записей всегда будет одинаковым vals
иkeys
будут в согласованном порядке.
Таким образом, для карты m
,
(= (keys m) (map key m))
(= (vals m) (map val m))
(= m (zipmap (keys m) (vals m)))
В настоящее время эта последовательность, по-видимому, не зависит от порядка вставки. Я проверил это на наборах, случайным образом перетасовывая случайные целые числа.