Гарантируют ли записи порядок, когда seq'd? - PullRequest
0 голосов
/ 25 июня 2018

Я пишу некоторый код, где мне нужно map format для каждого значения записи.Чтобы сэкономить на дублировании записи, было бы очень удобно, если бы я мог полагаться на записи, имеющие установленный порядок.Вот как это выглядит сейчас:

(defrecord Pet [health max-health satiety max-satiety])

(let [{:keys [health max-health satiety max-satiety]} pet
        [h mh s ms] (mapv #(format "%.3f" (double %))
                          [health max-health satiety max-satiety])]
  ...)

В идеале, я хотел бы написать это, используя vals:

(let [[h mh s ms] (mapv #(format "%.3f" (double %)) (vals pet))]
  ...)

Но я не могу найти какой-либо окончательнойисточники, если записи имеют гарантированный порядок, когда seq 'd.Из моего тестирования они кажутся заказанными.Я попытался создать массивную запись (в случае, если записи полагаются на отсортированную коллекцию, когда она маленькая):

(defrecord Order-Test [a b c d e f g h i j k l m n o p q r s t u v w x y z
                       aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu vv ww xx yy zz])

(vals (apply ->Order-Test (range 52)))
=> (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51)

И, похоже, они поддерживают порядок.

Может кто-нибудь проверить это?


Для этого точного сценария я предположил, что мог иметь reduce-kv над записью и заново связать значения, затем деконструировать.Это было бы довольно громоздким, хотя.Мне также любопытно, потому что я ничего не смог найти.

1 Ответ

0 голосов
/ 25 июня 2018

Как и во многих вещах в Clojure, нет гарантии, потому что нет спецификации.Если его нет в строке документации, вы принимаете это на свой страх и риск, даже если в текущей версии Clojure это действительно так.

Но я бы также сказал: это не совсем то, что записи значит , философски.Поля записи должны иметь индивидуальную семантику домена, и похоже, что в вашей записи они действительно есть.Это большой сюрприз, когда такая операция, как «взять N отчетливо значимых полей этой записи и обрабатывать их все одинаково», является правильной вещью, и она заслуживает того, чтобы ее прописали, когда вы это сделаете.

Вы можете, по крайней мере, делать то, что хотите, с немного меньшей избыточностью:

(let [[h mh s ms] (for [k [:health :max-health, :satiety :max-satiety]]
                    (format "%.3f" (get pet k)))]
  ...)

Лично я бы сказал, что вы неправильно моделируете свой домен: у вас явно есть понятие «ресурса» (здоровье и сытость).) который имеет как «текущее», так и «максимальное» значение.Они заслуживают того, чтобы их можно было сгруппировать по ресурсам, например,

{:health {:current 50 :max 80}
 :satiety {:current 3 :max 10}}

, и, сделав это, я бы сказал, что «набор ресурсов» питомца на самом деле представляет собой просто одно поле карты, а не N полей дляN ресурсов он содержит.Тогда весь этот вопрос упорядочения полей записей вообще не возникает.

...