Search code examples
clojureclojurescript

How do I build up an array using let in Clojure?


(test [1 2 3]) is returning [], not [1 2 3], why?

(defn test [some-array]
      (let [x []]
        (doseq [i some-array]
          (conj x i))
        x))

(test [1 2 3])

EDIT: a comment below suggested I am trying an imperative approach with a functional language, and that's probably correct. What I am trying to do is build up a vector of vectors using an initial sequence of values (inside a vector in this case) as starting data. I guess I could try to transform each value in the vector and return it, but that seems harder conceptually (from an imperative mindset) than taking a starting vector and using it to build out a new one and return that.

As an example, suppose I had a function that takes 1 and returns "one", and I wanted to have a function take [1 2 3] and return [[1 "one"][2 "two"][3 "three"]].


Solution

  • Clojure's focus is on immutable data and functional programming. Your code there feels like you want to do some imperative style ideas here.

    Your test there could as well be identity - a copy of some immutable data structure, is just the immutable data structure itself.

    If your example there is oversimplified and you want to "append" to some x with data inside it, you could use into.

    edit

    To transform a sequence one-by-one (e.g. each input results in a different output), use map (or mapv to get a vector and make it eager). E.g.

    (def numbers
      {1 "one"
       2 "two"
       3 "three"})
    
    (defn test [some-array]
      (mapv #(vector % (numbers %)) some-array))
    
    (println (test [1 2 3]))
    ; → [[1 one] [2 two] [3 three]]
    

    (Bonus points for using juxt as mapping function)