В Clojure, может ли быть предоставлено значение по умолчанию при использовании последовательной деструктуризации? - PullRequest
0 голосов
/ 06 ноября 2018

Похоже, что предоставление значения по умолчанию в ассоциативной деструктуризации хорошо задокументировано. https://clojure.org/guides/destructuring

Есть ли какой-нибудь известный способ указать значение по умолчанию при последовательной деструктуризации?

Например:

    (let [[hey you guys] ["do" "re"]]
      (println hey)
      (println you)
      (println guys))

Output:
do
re
nil

Как бы вы предоставили значение по умолчанию для «парней»?

попробовал

(let [[hey you (or guys "me")] ["do" "re"]]

(let [[hey you #(or % "me")] ["do" "re"]]

и несколько вариантов

(let [[hey you guys :or "me"] ["do" "re"]]

Спасибо!

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Хороший обзор деструктуризации Clojure можно найти здесь:

http://blog.brunobonacci.com/2014/11/16/clojure-complete-guide-to-destructuring/

Вы можете получить желаемое с помощью простой функции:

(defn apply-defaults
  [vals defaults]
  (vec (map-indexed
         (fn [idx val-default]
           (or (get vals idx) ; replaces both missing and `nil` values
             val-default))
         defaults)))

с результатом:

data      => [:a     nil    :c]
defaults  => [:def-a :def-b :def-c :def-d]

(apply-defaults data defaults) => [:a :def-b :c :def-d]

Обратите внимание, что вы должны изменить его, если хотите сохранить какие-либо значения nil во входных данных.

0 голосов
/ 08 ноября 2018

Если длина короткая, вы можете сделать это:

(let [[hey you guys] (merge defaults values)]
      (println hey)
      (println you)
      (println guys))

Слияние - это функция, которую вы должны определить / выбрать в зависимости от желаемого поведения, вероятно, она будет одной из этих двух (как в предыдущих ответах):

  1. Перезаписать значения в defaults, которые присутствуют в values
  2. concat значения из первого отсутствуют
0 голосов
/ 06 ноября 2018

Нет, я не верю, что есть способ предложить значения по умолчанию при неассоциативной деструктуризации.

Было бы несколько способов сделать это, в зависимости от того, что вы хотите. Ближайшие к предоставленным вами фрагментам могут быть:

(let [input ["do" "re"]
      defaults ["def1" "def2" "def3" "def4"]
      [hey you guys] (concat input (drop (count input) defaults))]
  (println hey you guys)) ;; do re def3

Если у вас есть только значение по умолчанию для 3-го аргумента, вы можете использовать:

(let [[hey you guys] (conj ["do" "re"] "def3")]
  (println hey you guys)) ;; do re def3

или

(let [[hey you guys] ["do" "re"]
      guys (or guys "def3")]
  (println hey you guys)) ;; do re def3
...