Add two collections in clojure - clojure

How to add two collections efficiently in clojure ?
I tried following one. I want to know is there any other method efficient than this.
(reduce #(conj %1 %2) collection01 collection02)

It depends on what you want to achieve. If what you want in the result is a collection of specified type, that contains all element of given collections, then into is appropriate: (into coll1 coll2) returns collection of type (type coll1) with elements from coll1 and coll2.
On the other hand, if you just want to iterate over many collections (i.e. create a sequence of elements in the collections) then it is more efficient to use concat:
user> (concat [1 2 3] (list 4 5 6))
(1 2 3 4 5 6)

use into:
user> (into [1 2 3] [4 5 6])
[1 2 3 4 5 6]
user> (doc into)
-------------------------
clojure.core/into
([to from])
Returns a new coll consisting of to-coll with all of the items of
from-coll conjoined.
nil

Related

how to find whether a vector has consecutive elements in clojure

I am new to clojure
I am trying to find whether a vector in clojure has consecutive elements:
in python its simple using numpy
(np.diff(np.sort(np.array(numbers))))
But I am lost trying to find similar methods:
My strategy was to
subtract a vector with itself
make it a set and see if it contains first element as 1 and the length of set is 1
for example
(def x `(5 7 3 6 4))
Output would be (1 1 1 1)
I am confused how to work on this.
Try something like this:
(defn diff [vals]
(map - (next vals) vals))
This returns a list of differences between each pair of consecutive elements are equal. It works because next simply offsets the sequence of values by one element.
Example usage:
(diff [1 2 2 3])
=> (1 0 1)
To test whether consecutive numbers exist, you simply need to check for the presence of the value 1 in this list.
Following your idea of getting the differences, after sorting you can use partition to get all the consecutive pairs and than use map to get all the differences. (Here it seemed more natural to get the reverse of the numpy diff, so the check is that every element is -1 instead of 1.)
(defn contains-consecutive? [xs]
(let [sorted (sort xs)
differences (map #(apply - %) (partition 2 1 sorted))]
(every? #(= -1 %) differences)))
user> (contains-consecutive? [])
true
user> (contains-consecutive? [1])
true
user> (contains-consecutive? [1 3 2])
true
user> (contains-consecutive? [1 3 4])
false
user> (contains-consecutive? '(5 7 3 6 4))
true
Clojure has a built-in dedupe function so an easy (but not particularly fast) answer is to dedupe and compare equals.
(defn consecutive?
[coll]
(not= coll (dedupe coll)))
(consecutive? [1 2 2 3]) ;; true
(consecutive? [1 2 3]) ;; false
Please see this list of documentation, especially the Clojure CheatSheet. You are looking for the function partition. You can use it like this:
(ns tst.demo.core
(:use tupelo.test))
(defn pair-delta
[pair]
(let [[a b] pair]
(- b a)))
(defn consectives?
[v]
(let [pairs (partition 2 1 (sort v))
deltas (mapv pair-delta pairs)
result (= #{1} (set deltas))]
result))
(dotest
(let [pos [1 2 3 6 5 4]
neg [1 2 3 6 5 ]]
(is= true (consectives? pos))
(is= false (consectives? neg))))
The template project shows how I like to set up a project, and includes my favorite helper functions.

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!

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.

how to paritally flatten a list in clojure?

Let's say I have a data structure like so:
[[1 2 3] [4 5 6] [[7 8 9] [10 11 12]]]
And what I want to end up with is:
[[1 2 3] [4 5 6] [7 8 9] [10 11 12]]
Is there any function that does this automatically?
Basically I'm converting/transforming a SQL result set to CSV, and there are some rows that will transform to 2 rows in the CSV. So my map function in the normal case returns a vector, but sometimes returns a vector of vectors. Clojure.data.csv needs a list of vectors only, so I need to flatten out the rows that got pivoted.
Mapcat is useful for mapping where each element can expand into 0 or more output elements, like this:
(mapcat #(if (vector? (first %)) % [%]) data)
Though I'm not sure if (vector? (first %)) is a sufficient test for your data.
A different approach using tree-seq:
(def a [[1 2 3] [4 5 6] [[7 8 9] [10 11 12]]])
(filter (comp not vector? first)
(tree-seq (comp vector? first) seq a))
I am stretching to use tree-seq here. Would someone with more experience care to comment on if there is a better way to return only the children other than using what is effectively a filter of (not branch?)
Clojure: Semi-Flattening a nested Sequence answers your question, but I don't want to mark this question as a duplicate of that one, since you're really asking a different question than he was; I wonder if it's possible to move his answer over here.

Idiomatically iterating over a 2 (or higher) dimensional sequence in Clojure

Is there a 'proper' way to iterate over a two-dimensional sequence in Clojure?
Suppose I had a list of lists of numbers, like this
((1 2 3)
(4 5 6)
(7 8 9))
and I wanted to generate a new list of lists with each number incremented by one. Is there an easy way to do this in Clojure without relying on nested maps or loop/recurs? I've been able to do it, but my solutions are ugly and I find them difficult to understand when I re-read them.
Thanks
What you describe is precisely what clojure.walk is for:
(def matrix [[1 2 3]
[4 5 6]
[7 8 9]])
(use 'clojure.walk :only [prewalk])
(prewalk #(if (number? %) (inc %) %) matrix)
=> [[2 3 4] [5 6 7] [8 9 10]]
Note 1: it is idiomatic to use vectors instead of parentheses for literal sequential collections.
Note 2: walk preserves type.
You can always just use a list comprehension. I find myself using them quite often coming from an imperative background so I don't know how idiomatic it is. In your specific case, you can do:
(for [my-list my-matrix] (map inc my-list))
For the two-dimensional case, you could do something like:
(map #(map inc %) my-two-d-list)
That's not too bad to read: apply the function #(map inc %) to each element in a list.
For the higher-order case, you're basically talking about tree-traversal. You'd want a function that takes in a tree and a function, and applies that function to each node in the tree. You can find functions for this in clojure.walk.
The other answers by Sean and Matt both show concise and effective ways of getting the right result.
However there are some important extensions you can make to this:
It would be nice to handle the case of higher dimensions
It is good to wrap the functionality in a higher order function
Example code:
;; general higher order function
(defn map-dimensions [n f coll]
(if (= n 1)
(map f coll)
(map #(map-dimensions (dec n) f %) coll)))
;; use partial application to specialise to 2 dimensions
(def map-2d (partial map-dimensions 2))
(map-2d inc
'((1 2 3)
(4 5 6)
(7 8 9)))
=> ((2 3 4) (5 6 7) (8 9 10))
Since the introduction of core.matrix in 2013, this is now a much better way of handling operations over multi-dimensional arrays:
(use 'clojure.core.matrix)
(def M [[1 2 3]
[4 5 6]
[7 8 9]])
(emap inc M)
=> [[2 3 4 ]
[5 6 7 ]
[8 9 10]]
Advantages of using core.matrix:
Clean, idiomatic Clojure code
Lots of general purpose n-dimensional array manipulation functions - transpose, shape, reshape, slice, subarray etc.
Ability to plug in high performance array implementations (e.g. for big numerical arrays)
A belated answer, and maybe not exactly what is needed: you could try flatten. It will return a seq that you can iterate over:
(flatten '((1 2 3)
(4 5 6)
(7 8 9)))
user=> (1 2 3 4 5 6 7 8 9)
And in order to increment matrix elements and reassemble the matrix:
(partition 3 (map inc (flatten '((1 2 3)
(4 5 6)
(7 8 9)))))