Search code examples
clojuredestructuring

destructure vector by index


I'd like to know if there is a way to destructure a vector by index. Basically, a shorthand that would allow me to avoid:

(defn f [v]
    (let [x (nth v 4)
          y (nth v 5)]
        (println x y)))

This is my basic problem:

user=> (defn f [{x 4 y 5}] (println x y))
#'user/f
user=> (f [0 1 2 3 4 5 6])
4 5
nil
user=> (f (apply vector (range 10)))
4 5
nil
user=> (f (range 10))
5 nil
nil
user=>

Solution

  • Answer to the original question about destructuring vectors:

    Vectors are associative, so you can use associative destructuring:

    (let [{x 4 y 5} [0 1 2 3 4 5 6]]
      [x y])
    ;= [4 5]
    

    Responding to the comment below, this works everywhere any destructuring forms work, including in fn parameter lists:

    ((fn [{x 4 y 5}] [x y]) [0 1 2 3 4 5 6])
    ;= [4 5]
    

    Answer to the new question about destructuring seqs:

    If you pass a seq to a function defined as above in place of a vector, the rule for associative destructuring of seqs will be applied. Namely, the seq will first be poured into a hash map -- (range 10) becomes {0 1 2 3 4 5 6 7 8 9} at this stage -- and then this hash map will be destructured as a map.

    There is no way of destructuring seqs by index. This is by design, as seqs are not meant for applications requiring fast random access.