How to combine sequences in clojure? - clojure

I have the following sequences
(def a [1 2 3 4])
(def b [10 20 30 40])
(def c [100 200 300 400])
I want to combine the sequences element by element:
(... + a b c)
To give me:
[111 222 333 444]
Is there a standard function available to do so? Or alternatively what is a good idiomatic way to do so?

if you use clojure-1.4.0 or above, you can use mapv:
user> (mapv + [1 2 3 4] [10 20 30 40] [100 200 300 400])
[111 222 333 444]

The function you are looking for is map.
(map + [1 2 3 4] [10 20 30 40] [100 200 300 400])
;=> (111 222 333 444)
Note that map returns a lazy sequence, and not a vector as shown in your example. But you can pour the lazy sequence into an empty vector by using the into function.
(into [] (map + [1 2 3 4] [10 20 30 40] [100 200 300 400]))
;=> [111 222 333 444]
Also, (for completeness, as it is noted in another answer) in Clojure 1.4.0+ you can use mapv (with the same arguments as map) in order to obtain a vector result.

Related

How to filter decreasing element in an increasing vector?

For example
[1 2 3 40 7 30 31 32 41]
after filtering should be
[1 2 3 30 31 32 41]
The problem doesn't seem very simple because I'd like to maximize the size of the resulting vector, so that if the starting vector is
[1 2 3 40 30 31 32 41 29]
I prefer this result
[1 2 3 30 31 32 41]
than just
[1 2 3 29]
Your problem is known as the longest increasing subsequence.
Via rosetta code:
(defn place [piles card]
(let [[les gts] (->> piles (split-with #(<= (ffirst %) card)))
newelem (cons card (->> les last first))
modpile (cons newelem (first gts))]
(concat les (cons modpile (rest gts)))))
(defn a-longest [cards]
(let [piles (reduce place '() cards)]
(->> piles last first reverse)))
(a-longest [1 2 3 40 30 31 32 41 29])
;; => (1 2 3 30 31 32 41)
Could probably be optimized to use transients if you care about performance.

Clojure vector manipulation

I have a vector of 4 numbers: [11 23 37 55]; I want to produce a sequence with 3 numbers where each of them is the result of the difference between the n+1 and the n element: ( (23-11) (37-23) (55-37)) = (12 14 28)
How can I do that in clojure?
Thx
This can be done easily with map.
user=> (def v [11 23 37 55])
#'user/v
user=> (map - (rest v) v)
(12 14 18)
when it gets more than two args, it takes elements from each sequence as the positional arguments to the function.

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.

How To Generate Multiple Calls To Function With One Arg In Sequence

I want to take a sequence [44 1 11] generated using (map #(nth %1 0 nil) v1) and feed (map) that into successive calls to the same function. I am just not sure which Clojure builtin or builtins to use other than for.
Here are the details.
Given these two vectors:
(def v1 [[44 2 3 4 5]
[1 6 7 5 10]
[11 12 13 14 15]])
(def v2 [[1 2 3 4 44]
[1 6 7 5 1]
[11 12 13 14 44]])
and this function
(defn ret-non-match-rows
"Expects a sequence of sequences, like what is returned from clojure-csv.
Returns all csv rows that do not match cmp-val at cmp-col-idx."
[s-o-s cmp-val cmp-col-idx]
(filter (complement nil?)
(map #(if (ret-col-match %1 cmp-val cmp-col-idx) nil %1) s-o-s) ))
So I am asking for help in how to feed (map) [44 1 11] into ret-non-match-rows like this
(ret-non-match-rows v2 44 4)
(ret-non-match-rows v2 44 1)
(ret-non-match-rows v2 44 11)
but using Clojure built-ins to generate those individual calls.
Thank You.
Edit:
The following gives me what I want, but I'm wondering if there is a cleaner way to do it.
(def ssn-1 [44 1 11])
(def tst (partial ret-non-match-rows v2 4))
(map #(tst %1) ssn-1)
I get back a sequence of sequences and will parse that to get my results.
Maybe you want this:
(map (partial ret-non-match-rows v2 44) (map first v1))
(assuming the 4 in the first example call is a typo and should be 44)

Doseq evaluates 1 x for every y. Is there any way to make it evaluate 1 x for 1 y and so on in Clojure?

I wasn't really sure how to phrase the name of this thread, so if you can clarify it any, please do so.
My example code is this:
(doseq [x [1 2 3] y [3 2 1]] (println (str x y)))
The output of that code is:
13
12
11
23
22
21
33
32
31
nil
I understand that list comprehensions, and doseq both evaluate like this. Is there another way to do this, so that instead of 1 element of x being used for every element of y, and so on, 1 element of x is used with 1 element of y and so on, so that the output would instead be:
13
22
31
Sorry if I'm not phrasing this right, I just can't seem to put it in words right.
EDIT: I think you can do this in Haskell with list comprehensions and a language extension. ParallelListComps or something.
You can simply do
(doseq [[x y] (map vector [1 2 3] [3 2 1])]
(println (str x y)))
(partition 2
(interleave [1 2 3] [3 2 1]))
interleave yields a sequence of alternating elements from the given sequences and partition groups this sequence into sequences of n elements.
This is more succint:
(doall (map println [1 2 3] [3 2 1]))