Can I transduce / educe over multiple collections without concatting them - clojure

Below is a bare-bones version of what I'm doing:
(eduction (map inc) (concat [1 2] [3 4]))
; -> (2 3 4 5)
Is there a way to get the same eduction, without having to pay the cost of concat, which creates an intermediate lazy seq?
The following would perhaps already be a bit less wasty, as instead of the lazy seq, we just have a vector, but I wonder if even that can be avoided.
(eduction (comp cat (map inc)) [[1 2] [3 4]])

It may be simplest to process your collections separately and combine the results. There is, in fact, an easy reducers-based solution that does exactly that under the covers.
The clojure.core.reducers namespace has cat, a combining function for fold, that you can repurpose to construct a reducible concatenation of your vectors.
(require '[clojure.core.reducers :as r])
(eduction (map inc) (r/cat [1 2] [3 4]))
;; => (2 3 4 5)
This avoids the lazy sequence used in concat. If you have more than two vectors, you can concatenate them all with (reduce r/cat [] colls) or similar.
This approach did speed up some of the experiments I did, though not your particular example.

You can also do this without the reducer just using the built in cat transducer
(eduction (comp cat (map inc)) [[1 2] [3 4]])
;; => (2 3 4 5)

Related

How can i loop through a Collection in Clojure?

I have a Matrix and i want to print the rows of it.
I tried to implement it like this but i dont know how to loop and get the other elements!
(defn p! [args]
(println (first args))
(drop args))
(p! [[1 2] [3 4]]) --> [1 2]
the output should look like this
;; 12
;; 34
I would suggest using the core.matrix facilities for this task. It has a mature and time-tested API. Among other things, it provides you with a pm function that pretty-prints a matrix and accepts a custom element formatter as a parameter.
You might find its implementation interesting, since it can give you an idea of printing array-like structures. (TL;DR: It approaches it with a recursive algorithm that employs a dotimes fn quite heavily.)
With this library you might end up implementing your p! fn like this:
(require '[clojure.core.matrix :as mx])
(defn p! [args]
(mx/pm (mx/matrix args)))
(p! [[1 2] [3 4]])
[[1 2]
[3 4]]
=> nil
If you would like to keep things simple and/or omit the brackets, then the easiest implementation would be along these lines:
(defn p! [args]
(doseq [row args]
(println (clojure.string/join " " row))))
(p! [[1 2] [3 4]])
1 2
3 4
=> nil
Cheers!

Good way in clojure to map function on multiple items of coll or seqence

I'm currently learning Clojure, and I'm trying to learn how to do things the best way. Today I'm looking at the basic concept of doing things on a sequence, I know the basics of map, filter and reduce. Now I want to try to do a thing to pairs of elements in a sequence, and I found two ways of doing it. The function I apply is println. The output is simply 12 34 56 7
(def xs [1 2 3 4 5 6 7])
(defn work_on_pairs [xs]
(loop [data xs]
(if (empty? data)
data
(do
(println (str (first data) (second data)))
(recur (drop 2 data))))))
(work_on_pairs xs)
I mean, I could do like this
(map println (zipmap (take-nth 2 xs) (take-nth 2 (drop 1 xs))))
;; prints [1 2] [3 4] [5 6], and we loose the last element because zip.
But it is not really nice.. My background is in Python, where I could just say zip(xs[::2], xs[1::2]) But I guess this is not the Clojure way to do it.
So I'm looking for suggestions on how to do this same thing, in the best Clojure way.
I realize I'm so new to Clojure I don't even know what this kind of operation is called.
Thanks for any input
This can be done with partition-all:
(def xs [1 2 3 4 5 6 7])
(->> xs
(partition-all 2) ; Gives ((1 2) (3 4) (5 6) (7))
(map (partial apply str)) ; or use (map #(apply str %))
(apply println))
12 34 56 7
The map line is just to join the pairs so the "()" don't end up in the output.
If you want each pair printed on its own line, change (apply println) to (run! println). Your expected output seems to disagree with your code, so that's unclear.
If you want to dip into transducers, you can do something similar to the threading (->>) form of the accepted answer, but in a single pass over the data.
Assuming
(def xs [1 2 3 4 5 6 7])
has been evaluated already,
(transduce
(comp
(partition-all 2)
(map #(apply str %)))
conj
[]
xs)
should give you the same output if you wrap it in
(apply println ...)
We supply conj (reducing fn) and [] (initial data structure) to specify how the reduce process inside transduce should build up the result.
I wouldn't use a transducer for a list that small, or a process that simple, but it's good to know what's possible!

Clojure: more idiomatic pairing of elements from lists of unequal sizes?

I would like to create a list of pairs from cols, and patch. cols would have much more elements. Element in patch would be repeated in the pairing.
For example,
(element-wise-patch '(1 3 5 7 9) '(2 4) '())
([1 2] [3 4] [5 2] [7 4] [9 2])
Here is my attempt to implement the semantics. I hope to learn more idiomatic, and simpler solution.
(defn element-wise-patch [cols patch patched]
(if (<= (count cols) (count patch))
(concat patched (map vector cols patch))
(let [[compatible remaining] (split-at (count patch) cols)]
(element-wise-patch remaining patch (concat patched (map vector compatible patch)))))
I feel that there might be already existing construct to do such patching pairing. Also my description might not be proper enough to associate similar solutions.
Please give me some pointer, or just help me define my problem clearer.
Thanks in advance for your help!
Quite simply:
(map vector [1 3 5 7 9] (cycle [2 4]))

How to iterate over ArrayMap in clojure?

I am totally new to clojure (started learning yesterday) and functional programming so please excuse my ignorance. I've been trying to read a lot of the clojure documentation, but much of it is totally over my head.
I'm trying to iterate over an ArrayMap of this set up:
{city1 ([[0 0] [0 1] [1 1] [1 0]]), city2 ([[3 3] [3 4] [4 4] [4 3]]), city3 ([[10 10] [10 11] [11 11] [11 10]])}
(^hopefully that syntax is correct, that is what it looks like my terminal is printing)
where the city name is mapped to a vector of vectors that define the points that make up that city's borders. I need to compare all of these points with an outside point in order to determine if the outside point is in one of these cities and if so which city it is in.
I'm using the Ray Casting Algorithm detailed here to determine if an outside point is within a vector of vectors.
Maps actually implement the clojure.lang.ISeq interface which means that you can use all the higher-level sequence operations on them. The single elements are pairs of the form [key value], so, to find the first element that matches a predicate in-city? you could e.g. use some:
(some
(fn [[city-name city-points]] ;; the current entry of the map
(when (in-city? the-other-point city-points) ;; check the borders
city-name)) ;; return the name of a matching city
cities)
You might also use keep to find all elements that match the predicate but I guess there is no overlap between cities in your example.
Update: Let's back off a little bit, since working with sequences is fun. I'm not gonna dive into all the sequence types and just use vectors ([1 2 3 ...]) for examples.
Okay, for a start, let's access our vector:
(first [1 2 3]) ;; => 1
(rest [1 2 3]) ;; => [2 3]
(last [1 2 3]) ;; => 3
(nth [1 2 3] 1) ;; => 2
The great thing about functional programming is, that functions are just values which you can pass to other functions. For example, you might want to apply a function (let's say "add 2 to a number") to each element in a sequence. This can be done via map:
(map
(fn [x]
(+ x 2))
[1 2 3])
;; => [3 4 5]
If you haven't seen it yet, there is a shorthand for function values where % is the first parameter, %2 is the second, and so on:
(map #(+ % 2) [1 2 3]) ;; => [3 4 5]
This is concise and useful and you'll probably see it a lot in the wild. Of course, if your function has a name or is stored in a var (e.g. by using defn) you can use it directly:
(map pos? [-1 0 1]) ;; => [false false true]
Using the predicate like this does not make a lot of sense since you lose the actual values that produce the boolean result. How about the following?
(filter pos? [-1 0 1]) ;; => [1]
(remove pos? [-1 0 1]) ;; => [-1 0]
This selects or discards the values matching your predicate. Here, you should be able to see the connection to your city-border example: You want to find all the cities in a map that include a given point p. But maps are not sequences, are they? Indeed they are:
(seq {:a 0 :b 1}) ;; => [[:a 0] [:b 1]]
Oh my, the possibilities!
(map first {:a 0 :b 1}) ;; => [:a :b]
(filter #(pos? (second %)) {:a 0 :b 1}) ;; => [[:b 1]]
filter retrieves all the matching cities (and their coordinates) but since you are only interested in the names - which are stored as the first element of every pair - you have to extract it from every element, similarly to the following (simpler) example:
(map first (filter #(pos? (second %)) {:a 0 :b 1}))
:: => [:b]
There actually is a function that combines map and filter. It's called keep and return every non-nil value its predicate produces. You can thus check the first element of every pair and then return the second:
(keep
(fn [pair]
(when (pos? (second pair))
(first pair)))
{:a 0 b 1})
;; => [:b]
Everytime you see yourself using a lot of firsts and seconds, maybe a few rests inbetween, you should think of destructuring. It helps you access parts of values in an easy way and I'll not go into detail here but it can be used with sequences quite intuitively:
(keep
(fn [[a b]] ;; instead of the name 'pair' we give the value's shape!
(when (pos? b)
a))
{:a 0 :b 1})
;; => [:b]
If you're only interested in the first result you can, of course, directly access it and write something like (first (keep ...)). But, since this is a pretty common use case, you get some offered to you by Clojure. It's like keep but will not look beyond the first match. Let's dive into your city example whose solution should begin to make sense by now:
(some
(fn [[city-name city-points]]
(when (in-city? p city-points)
city-name))
all-cities)
So, I hope this can be useful to you.

Difference between doseq and for in Clojure

What's the difference between doseq and for in Clojure? What are some examples of when you would choose to use one over the other?
The difference is that for builds a lazy sequence and returns it while doseq is for executing side-effects and returns nil.
user=> (for [x [1 2 3]] (+ x 5))
(6 7 8)
user=> (doseq [x [1 2 3]] (+ x 5))
nil
user=> (doseq [x [1 2 3]] (println x))
1
2
3
nil
If you want to build a new sequence based on other sequences, use for. If you want to do side-effects (printing, writing to a database, launching a nuclear warhead, etc) based on elements from some sequences, use doseq.
Note also that doseq is eager while for is lazy. The example missing in Rayne's answer is
(for [x [1 2 3]] (println x))
At the REPL, this will generally do what you want, but that's basically a coincidence: the REPL forces the lazy sequence produced by for, causing the printlns to happen. In a non-interactive environment, nothing will ever be printed. You can see this in action by comparing the results of
user> (def lazy (for [x [1 2 3]] (println 'lazy x)))
#'user/lazy
user> (def eager (doseq [x [1 2 3]] (println 'eager x)))
eager 1
eager 2
eager 3
#'user/eager
Because the def form returns the new var created, and not the value which is bound to it, there's nothing for the REPL to print, and lazy will refer to an unrealized lazy-seq: none of its elements have been computed at all. eager will refer to nil, and all of its printing will have been done.