Clojure, concat multiple sequences into one - clojure

The following line: (repeat 4 [2 3])
gives me this: ([2 3] [2 3] [2 3] [2 3])
How do I create one vector or list from the above list of vectors so that I get this?: [2 3 2 3 2 3 2 3]
Thanks

concat is in fact exactly the function you want
user> (apply concat (repeat 4 [2 3]))
(2 3 2 3 2 3 2 3)
this even works with lazy input:
user> (take 8 (apply concat (repeat [2 3])))
(2 3 2 3 2 3 2 3)
This is an alternative:
user> (def flatten-1 (partial mapcat identity))
#'user/flatten-1
user> (flatten-1 (repeat 4 [2 3]))
(2 3 2 3 2 3 2 3)
it is compatible with laziness and unlike flatten preserves any substructure (only doing one level of flattening)
user> (take 12 (flatten-1 (repeat [2 3 [4]])))
(2 3 [4] 2 3 [4] 2 3 [4] 2 3 [4])

(take 8 (cycle [2 3]))
;; => (2 3 2 3 2 3 2 3)

(flatten x)
Takes any nested combination of sequential things (lists,
vectors, etc.) and returns their contents as a single, flat sequence.
(flatten nil) returns nil.
(flatten (repeat 4 [2 3])) ;(2 3 2 3 2 3 2 3)

Pedantically speaking, you asked for a vector, so:
(->> [2 3] cycle (take 8) vec)
I feel cycle is a little more appropriate than concat (though it uses concat itself) as it indicates "cycle through the elements of this sequence" rather than "concatenate the following sequences together". Just my two cents, matter of opinion.

Related

Clojure: 'folding' a sequence (partitioning, as it turned out)

What is the right way of turning a flat list like this:
(1 2 3 4 5 6 7 8 9)
into a sequence of vectors:
([1 2 3] [4 5 6] [7 8 9])
Sorry, I suppose this is something right out of the toolbox, but I can't think of the right keyword.
(->> '(1 2 3 4 5 6 7 8 9) (partition 3) (map vec))
Take the original list and then partition it by 3 and finally map each partition to a vector.
I think using the ->> macro makes it read nicer.
user> (def flat-seq (range 1 10))
#'user/flat-seq
user> (map vec (partition-all 3 flat-seq))
;=> ([1 2 3] [4 5 6] [7 8 9])

clojure implicit map explanation

I understand how map works but I am confused by this example:
(def check-sum
(fn [sequence]
(apply + (map *
(range 1 (inc (count sequence)))
sequence))))
The map part looks like this when given a sequence:
(map * (range 1 (inc (count [5 1 1 4 7 7 1 3 1 0]))) [5 1 1 4 7 7 1 3 1 0])
Which returns this:
(5 2 3 16 35 42 7 24 9 0)
I do not understand where the current item in the map is being multiplied. I would understand if it was using an anonymous function of the form #(* %) etc.
But there is no anonymous function in this example.
The first argument of map should be function and the number of parameter should be matched to the number of collections provided. So, if you want to pass an anonymous function, you should write the code like this:
(map #(* %1 %2) [1 3 5] [2 4 6])
;=> (2 12 30)
(map #(* %1 %2 %3) [1 3 5] [2 4 6] [3 5 7])
;=> (6 60 210)
But * itself is a function which can take any number of arguments (check (doc *) from REPL), you can write the code in a simpler form:
(map * [1 3 5] [2 4 6])
;=> (2 12 30)
(map * [1 3 5] [2 4 6] [3 5 7])
;=> (6 60 210)
* is applied to the set of first elements of each collection, set of second elements, ...
Other functions like +, -, / can be used in this way, too.
No anonymous function is needed, because the named function * is what's doing the multiplying. Two collections are passed to map, so it passes the corresponding elements from each collection to the * function.

Map with repeated argument clojure

Consider the following function as an example:
(defn f [x y] (+ x y))
I want to use this function to add 2 to each element of a vector:
[1 2 6 3 6]
I can use map:
(map f [1 2 6 3 6] [2 2 2 2 2])
But it seems a little ugly creating the second vector where every element is exactly the same.
So I thought using a closure was a better approach:
(map (fn g [x] (f x 2)) [1 2 6 3 6])
So my question is:
In clojure, what is the best way to use map when some arguments are not changing?
Just apply partial function
(map (partial + 2) [1 2 6 3 6]) => (3 4 8 5 8)
Approach 1: use repeat.
(repeat 2) gives you a lazy sequence of infinite 2s
In your case,
(map f [1 2 6 3 6] [2 2 2 2 2])
should be converted into
(map f [1 2 6 3 6] (repeat 2))
Approach 2: use anonymous function
(map #(f % 2) [1 2 6 3 6])

finding if a vector's all elements only appear once

I have a vector - [1 2 3 4]
I want to check that in the vector each element appears only once. How do I do it ? One way I can think of is to convert it into a set and then back into the vector and then compare both :) However I think there should be a simpler way ...
You can use distinct?:
(apply distinct? [1 2 3 4]) ;=> true
(apply distinct? [1 2 3 4 4]) ;=> false
You can use distinct:
(distinct [1 2 3 4 5 5]) -> [1 2 3 4 5]
For a check, you can do something like:
(= [1 2 3 4 5 5] (distinct [1 2 3 4 5 5]))

Unflattening a sequence to sequences of repeating elements (clojure)

In Clojure, how do you partition a sequence to subsequences of repeating elements? E.g. :
[1 2 2 3 3 3 4 2 2 1 1 1]
to
[[1] [2 2] [3 3 3] [4] [2 2] [1 1 1]]
I've been playing around with some examples trying to understand clojure better, and was stuck on this one for some time.
user> (partition-by identity [1 2 2 3 3 3 4 2 2 1 1 1])
((1) (2 2) (3 3 3) (4) (2 2) (1 1 1))
user> (vec (map vec (partition-by identity [1 2 2 3 3 3 4 2 2 1 1 1])))
[[1] [2 2] [3 3 3] [4] [2 2] [1 1 1]]
(map (juxt count first)
(partition-by identity [1 1 1 3 2 2]))
((3 1) (1 3) (2 2))
Three ones, then one three, followed by two twos!