Droidekas
Droidekas

Reputation: 3504

Return an array from let using doseq and into

I am trying to return a list from a let statement.

(let [data []]
 (doseq [x ["0" "1" "2" "3" "4"]]
  (into data (do-stuff x))) data)

However the data list is always empty.

I checked this answer on returning values from the let scope however could not fix this.

Upvotes: 2

Views: 727

Answers (2)

johnbakers
johnbakers

Reputation: 24771

If you are trying to understand the looping mechanism in Clojure, you are probably looking for this (assuming that what you are doing is just an exercise in how collections work):

(for [x ["1" "2" "3"]] x)

The result is:

("1" "2" "3")

Of course, if this is all you are going to do, you already have the collection and don't need to build it.

Based on your edit, do this:

(for [x ["1" "2" "3"]] (do-stuff x))

There are many other ways to do this type of stuff though, like using map or reduce and other tools, depending on the complexity of do-stuff and what it needs access to.

Remember, values in Clojure are immutable be default. You cannot mutate your data at all, it is fixed at a value of []. Unless you make it an atom, which is unnecessary for what you need. Functional programming is about building values, not mutating variables.

There are many ways to express what you are trying to do, but for is the list-building ("list comprehension") version of do-seq as they share the same general structure. Since your question was about do-seq, I discuss for for good measure. But map is a better choice here. If you really need it to be a vector as opposed to a lazy sequence, then use mapv.

If you needed something called data that holds these results, then just do this:

(let [data (for [x ["1" "2" "3"]] x)] ;;or map, etc
   ;;do something with data
 )

Upvotes: 4

Lee
Lee

Reputation: 144226

If you want to modify each element and return a vector you can use mapv:

(mapv do-stuff ["0" "1" "2" "3" "4"])

or you can use map if you just need a sequence output:

(map do-stuff ["0" "1" "2" "3" "4"])

or a for expression:

(for [x ["0" "1" "2" "3" "4"]] (do-stuff x))

for expressions return a sequence which you can convert into a vector using vec if required:

(vec (for [x ["0" "1" "2" "3" "4"]] (do-stuff x)))

Upvotes: 4

Related Questions