I've played around a bit with clojure before doing much more studying of lisp and I want to get back into clojure...
So I have this thing in common lisp:
(mapcar #'(lambda (x)
(incf (third (car (member x count-mx
:test #'equal
:key #'(lambda (x) (list (car x) (cadr x))))))))
transitions)
That for me in clojure translated to (not sure if this is good clojure):
(map (fn [x] (swap! (third (some #(if (= x (vec (first %) (second %))) %)
count-mx))
inc))
transitions)
where count-mx, if I used atoms to make the zeroes:
[[a a 0] [a b 0] [a c 0] [a d 0] [b a 0] [b b 0] [b c 0] [b d 0] [c a 0] [c b 0] [c c 0] [c d 0] [d a 0] [d b 0] [d c 0] [d d 0]]
and transitions:
[[a a] [a b] [b c] [c d] [d a] [a b] [b c]]
The objective being to increment [a a 0] to [a a 1] after mapping over transitions and seeing [a a]
Although the clojure line does work I cannot use it within a function or let because of immutability, how do I break out of my common lisp thinking? I quite like mapping and modifying values within something, but I'm not sure how to do this efficiently and/or correctly in clojure.
Edit (Improved answer)
I didn't know: Maps accept also vectors as keys.
In this case, we can directly take the pairs as keys and use update in combination with inc to update the values (by enhancing the value by 1). I use sorted-map because it looks nicer for presentation (sorted) - more performant would be to use (hash-map) or {} in the into expression.
(def m (into (sorted-map) ;; or: `{}` btw `(hash-map)`
(for [x '[a b c d] ;; nesting for-loop
y '[a b c d]] ;; for sunccinct creation
{[x y] 0}))) ;; of all combinations
m
;; => {[a a] 0, [a b] 0, [a c] 0, [a d] 0,
;; [b a] 0, [b b] 0, [b c] 0, [b d] 0,
;; [c a] 0, [c b] 0, [c c] 0, [c d] 0,
;; [d a] 0, [d b] 0, [d c] 0, [d d] 0}
(def transitions '[[a a] [a b] [b c] [c d]
[d a] [a b] [b c]])
(def m' (reduce (fn [a-map a-transition]
(update a-map a-transition inc))
m
transitions))
m'
;; => {[a a] 1, [a b] 2, [a c] 0, [a d] 0,
;; [b a] 0, [b b] 0, [b c] 2, [b d] 0,
;; [c a] 0, [c b] 0, [c c] 0, [c d] 1,
;; [d a] 1, [d b] 0, [d c] 0, [d d] 0}
(reduce (fn [mp key] (update mp key inc)) m '[a b c]) expands to:
(update (update (update m 'a inc) 'b inc) 'c inc)
therefore (in an accumulating manner) sequentially updating the values of each key given in transitions.
We convert the sorted map into the nested vector form by:
(def m'' (into [] (map (comp vec flatten) (seq m'))))
m''
;; => [[a a 1] [a b 2] [a c 0] [a d 0]
;; [b a 0] [b b 0] [b c 2] [b d 0]
;; [c a 0] [c b 0] [c c 0] [c d 1]
;; [d a 1] [d b 0] [d c 0] [d d 0]]
We can generalize them to functions:
(defn update-map-by-transitions
"Update the map `m` successively by transitions"
[m transitions & {:keys [func] :or {func inc}}]
(reduce (fn [m' tr] (update m' tr func))
m
transitions))
(defn map-to-vecs
"Transform transition map to flatten vectors"
[m & {:keys [vec-func] :or {vec-func flatten}}]
(into [] (map (comp vec vec-func) (seq m))))
(def m' (update-map-by-transitions m transitions))
(def m'' (map-to-vecs m' :vec-func flatten))
m''
;; [[a a 1] [a b 2] [a c 0] [a d 0]
;; [b a 0] [b b 0] [b c 2] [b d 0]
;; [c a 0] [c b 0] [c c 0] [c d 1]
;; [d a 1] [d b 0] [d c 0] [d d 0]]
;; or do:
(def m''' (map-to-vecs m' :vec-func identity))
m'''
;; [[[a a] 1] [[a b] 2] [[a c] 0] [[a d] 0]
;; [[b a] 0] [[b b] 0] [[b c] 2] [[b d] 0]
;; [[c a] 0] [[c b] 0] [[c c] 0] [[c d] 1]
;; [[d a] 1] [[d b] 0] [[d c] 0] [[d d] 0]]
Original answer
I am also coming from Common Lisp. By the way, you abbreviate it CL or "Lisp". But CLISP actually means one of the many implementations of CL (next to sbcl, abcl, ECL, etc.). So don't call CL clisp ... (to avoid others to be annoyed about it).
I think using nested vectors for this task is tedious and - when scaling up later - less performant.
Instead, prefer maps. They have the function update and in case of nested maps update-in to manipulate and "mutate" the values of a map which will prove very handy for this task.
To take a vec [a b c d] and generate {a 0 b 0 c 0 d 0}, I would define:
(defn mapper [vec default-val]
(into {} (for [x vec] {x default-val})))
(mapper '[a b] 0) ;; => {a 0 b 0}
Now, we want two keys for storing a count value for them: Nest the maps:
(def m (mapper '[a b c d] (mapper '[a b c d] 0)))
m
;; =>{a {a 0, b 0, c 0, d 0},
;; b {a 0, b 0, c 0, d 0},
;; c {a 0, b 0, c 0, d 0},
;; d {a 0, b 0, c 0, d 0}}
We can anytime convert them back to your favorized nested vector form (I admit, it is better human readable):
(defn nested-maps-to-vecs [nested-map]
(vector (for [[k v] nested-map
[ik iv] v]
[k ik iv])))
(nested-maps-to-vecs m)
;;=> [[a a 0] [a b 0] [a c 0] [a d 0]
;; [b a 0] [b b 0] [b c 0] [b d 0]
;; [c a 0] [c b 0] [c c 0] [c d 0]
;; [d a 0] [d b 0] [d c 0] [d d 0]]
Now define transitions:
(def transitions '[[a a] [a b] [b c] [c d] [d a] [a b] [b c]])
Using inc function for update and the handy update-in we can
"mutate" the values of the map:
(def m' (reduce (fn [a-map a-transition] (update-in a-map a-transition inc)) m transitions))
m'
;; => {a {a 1, b 2, c 0, d 0},
;; b {a 0, b 0, c 2, d 0},
;; c {a 0, b 0, c 0, d 1},
;; d {a 1, b 0, c 0, d 0}}
(nested-maps-to-vecs m')
;; => [[a a 1] [a b 2] [a c 0] [a d 0]
;; [b a 0] [b b 0] [b c 2] [b d 0]
;; [c a 0] [c b 0] [c c 0] [c d 1]
;; [d a 1] [d b 0] [d c 0] [d d 0]]
Voila!
(update-in a-map a-transition inc) gets e.g. [a b] and accesses in the nested map with the key sequence a and then b and takes the value which is in that "place" and applies inc to it and "stores" the result into that "place".
Well, it doesn't store it actually, but it returns a new map with the updated value.
This new map is the new a-map in the reduce function and taking the next a-transition this updated map will be further updated.
So reduce is the trick to "accumulate" the updates by constant update and capture of the updated map while walking through the transitions sequence.
Clojure has a very efficient way to "update" its immutable structures. It saves only the changes while referring to the unchanged rest. Therefore this "generation of a new updated map" by update sounds worse than it actually is: It is actually highly efficient performance- as well as memory footprint-wise. This special storing strategy cannot be pursued by Common Lisp and other Lisps or languages, because of mutability. Only pure functional languages with ensured immutability of data like Clojure or Haskell can use this kind of strategy for storing and updating their immutable data.
Clojure has however also mutability in atoms which has to be specifically declared to be an atom. In this case, to use atoms as values in the map or the nested vectors would be not very the Clojure way.
I am also still trying to wrap my head around this all.
Have fun in your journey!
Use frequencies to count the transitions, then a for list comprehension to build the desired result:
(defn mat [transitions]
(let [freqs (frequencies transitions)
verts '[a b c d]]
(for [x verts
y verts]
[x y (get freqs [x y] 0)])))
(def t '[[a a] [a b] [b c] [c d] [d a] [a b] [b c]])
(mat t) ; => ([a a 1] [a b 2] [a c 0] [a d 0]
; [b a 0] [b b 0] [b c 2] [b d 0]
; [c a 0] [c b 0] [c c 0] [c d 1]
; [d a 1] [d b 0] [d c 0] [d d 0])
This is how I would do it in clojure.
user> (def count-mx '[[a a 0] [a b 0] [a c 0] [a d 0] [b a 0] [b b 0] [b c 0] [b d 0] [c a 0] [c b 0] [c c 0] [c d 0] [d a 0] [d b 0] [d c 0] [d d 0]])
#'user/count-mx
user> (def transitions '[[a a] [a b] [b c] [c d] [d a] [a b] [b c]])
#'user/transitions
user> (reduce (fn [cmx xtn]
(mapv (fn [[x1 x2 c :as mx]]
(let [x (pop mx)]
(if (= x xtn)
(conj x (inc c))
mx)))
cmx))
count-mx
transitions)
[[a a 1]
[a b 2]
[a c 0]
[a d 0]
[b a 0]
[b b 0]
[b c 2]
[b d 0]
[c a 0]
[c b 0]
[c c 0]
[c d 1]
[d a 1]
[d b 0]
[d c 0]
[d d 0]]
user>
It's better to just think about pure functions and not worry about doing mutation for efficiency. For example, in this above example, count-mx is still the same original value.
Since it seems that the data items being counted are pairs like [:a :c], I would use a pair vector as the map key. Also, in Clojure it is more common to use keywords like :a as data tokens rather than symbols like a.
First define the tokens, and the pairs of tokens:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(def tokens [:a :b :c :d])
(def pairs (vec (for [x tokens
y tokens]
[x y])))
and then initialize a count map with a zero total for each pair:
(def counts (into (sorted-map) (zipmap pairs (repeat 0))))
(dotest
(is= pairs [[:a :a] [:a :b] [:a :c] [:a :d]
[:b :a] [:b :b] [:b :c] [:b :d]
[:c :a] [:c :b] [:c :c] [:c :d]
[:d :a] [:d :b] [:d :c] [:d :d]])
(is= counts
{[:a :a] 0, [:a :b] 0, [:a :c] 0, [:a :d] 0,
[:b :a] 0, [:b :b] 0, [:b :c] 0, [:b :d] 0,
[:c :a] 0, [:c :b] 0, [:c :c] 0, [:c :d] 0,
[:d :a] 0, [:d :b] 0, [:d :c] 0, [:d :d] 0}))
The unit test shows all is as we desire.
Then a simple accumulator function using update-in
(defn accumulator
[data]
(let [curr-cnt (atom counts)]
(doseq [item data]
(swap! curr-cnt update-in [item] inc))
(deref curr-cnt)))
Now, define some sample data and verify the result:
(def data [[:a :a] [:a :a] [:a :a] [:a :b] [:b :c] [:c :d] [:d :a] [:a :b] [:b :c]])
(dotest
(is= (accumulator data)
{[:a :a] 3,
[:a :b] 2,
[:a :c] 0,
[:a :d] 0,
[:b :a] 0,
[:b :b] 0,
[:b :c] 2,
[:b :d] 0,
[:c :a] 0,
[:c :b] 0,
[:c :c] 0,
[:c :d] 1,
[:d :a] 1,
[:d :b] 0,
[:d :c] 0,
[:d :d] 0}))
Built using my favorite template project.
I am currenly using a function
(def mymap {})
(defn function1 [var1 var2 var3 var4 var5]
;calls another functions with all variables.
(function2 var1 var2 var3 var4 var5)
)
But as this is having more parameters I would like to convert this to a map before calling functions2.
(function2((assoc mymap (keyword var1) var1
(keyword var2) var2
(keyword var3) var3
(keyword var4) var4
(keyword var5) var5 ))
)
Is this the correct way? Do we have better way to do this(In java we direclty use some objects in this scenario)
For general function args, I always go in order from the biggest to the smallest,
in either size or "importance" (somewhat subjective).
However, if you have more than 3 args, I prefer to pass a map containing the args and appropriate keyword names.
The Tupelo Clojure library has some tools to make this easy. The macro vals->map takes multiple variable names and constructs a map from the (keywordized) variable name to its value, like:
(let [ctx (let [a 1
b 2
c 3
d 4
e 5]
(t/vals->map a b c d e))]
(is= ctx {:a 1 :b 2 :c 3 :d 4 :e 5})
The macro with-map-vals does the opposite, deconstructing map values into local variables named for their keys. It is similar to the Clojure :keys destructuring, but in (IMHO) a more natural form:
(let [{:keys [a b c d e]} ctx] ; Clojure destructing syntax
(is= [a b c d e] [1 2 3 4 5]))
(t/with-map-vals ctx [a b c d e]
(is= [a b c d e] [1 2 3 4 5])
(is= 15 (+ a b c d e)))
(t/with-map-vals ctx [b a d c e] ; order doesn't matter
(is= [a b c d e] [1 2 3 4 5])
(is= 15 (+ a b c d e)))
(t/with-map-vals ctx [b a d] ; can ignore stuff you don't care about
(is= [d a b] [4 1 2]))
(throws?
(t/with-map-vals ctx [a b z] ; throws if key doesn't exist
(println "won't ever get here")))))
If you have nested data in maps and/or vectors, you can use the more powerful destruct and restruct tools. Here is a brief example (from the unit tests):
(let [info {:a 1
:b {:c 3
:d 4}}
mania {:x 6
:y {:w 333
:z 666}}]
(t/it-> (t/destruct [info {:a ?
:b {:c ?
:d ?}}
mania {:y {:z ?}}] ; can ignore unwanted keys like :x
(let [a (+ 100 a)
c (+ 100 c)
d z
z 777]
(restruct-all)))
(t/with-map-vals it [info mania]
(is= info {:a 101, :b {:c 103, :d 666}})
(is= mania {:x 6, :y {:w 333, :z 777}})))
As you can see, a question mark ? will cause the corresponding value to be destructed into a variable named for the corresponding keyword. It is also possible to create explicit variable names like so:
(dotest
(let [info {:a 777
:b [2 3 4]}
mania [{:a 11} {:b 22} {:c [7 8 9]}]]
(let [z ::dummy]
(t/it-> (t/destruct [info {:a z
:b [d e f]}
mania [{:a ?} BBB {:c clutter}]]
(let [clutter (mapv inc clutter)
BBB {:BBB 33}
z 77
d (+ 7 d)]
(restruct-all)))
(t/with-map-vals it [info mania]
(is= info {:a 77, :b [9 3 4]})
(is= mania [{:a 11} {:BBB 33} {:c [8 9 10]}]))))))
It also works for mixed maps & vectors:
(let [data {:a [{:b 2}
{:c 3}
[7 8 9]]} ]
(t/destruct [data {:a [{:b p}
{:c q}
[r s t]]} ]
(is= [2 3 7 8 9] [p q r s t])))
I want to do this
(let [[a b c] '(1 2 3)]
{:a a :b b :c c}) ;; gives {:a 1, :b 2, :c 3}
But with [a b c] saved in a vector like this
(def vect '[a b c])
(let [vect '(1 2 3)]
{:a a :b b :c c}) ;; complains that a is unresolved
Is it possible to somehow use a var to define how to destructure?
The error occurs, because in this snippet:
(let [vect '(1 2 3)]
{:a a :b b :c c})
You're binding vect to '(1 2 3). The vect earlier defined as '[a b c] earlier will be shadowed by the local let binding. a,b and c will be left unbound.
The only way I think you can do what you ask is by using (abusing?) eval/macros, and building up the exact form that you need.
(eval (list 'let [vect ''(1 2 3)] '{:a a :b b :c c}))
;; => {:a 1 :b 2 :c 3}
However, I really urge you to put in some hammock time here and think about why you need to destructure using a var, and possible alternative designs. The solution above is already pretty hacky and using it could get very ugly...
I would agree with Daniel to possibly rethink the reason why you need to do it, e.g. what exactly the problem is you are after.
But if you insist :), pretending that we literally work with "a b c.."s, you can do this:
user=> (def xs '[a b c])
#'user/xs
user=> (into {} (for [v xs] [(keyword v) v]))
{:a a, :b b, :c c}
Given the following tree (or any other form in Clojure including maps and vectors):
'( (a b) (c d) )
I would like to generate a map in Clojure that indexes each sub-form according to a depth-first traversal of the entire form and also provides a vector (or list) of the indices of the form's children (if any).
0 -> a []
1 -> b []
2 -> (a b) [0 1]
3 -> c []
4 -> d []
5 -> (c d) [3 4]
6 -> ( (a b) (c d) ) [2 5]
I have so far only managed to use clojure.walk to produce the first part (indexing the subforms) but I am baffled as to how to generate the indices of the children as well. My code is appended at the end and produces:
user=> (depthFirstIndexing '( (a b) (c d) ))
{6 ((a b) (c d)), 5 (c d), 4 d, 3 c, 2 (a b), 1 b, 0 a}
So the indexes to the sub-forms are generated correctly according to depth-first traversal but I don't see how I can obtain the indices of the children of every sub-form. I tried to use the zippers module but I couldn't see how to perform a depth-first traversal to collect the indices.
half-way there code
(use 'clojure.walk)
(defn depthFirstIndexing [aform]
(let [counter (atom -1)
idxToSubform (atom {})
]
(postwalk (fn [x]
(def idx (swap! counter inc))
(swap! idxToSubform assoc idx x)
x)
aform)
#idxToSubform))
A walk is recursive and does not provide for an accumulator argument, which is why you have had to resort to updating atoms.
A zipper is iterative, so you can carry along other information without breaking a functional pattern.
The natural depth-first traversal is a pre-order traversal, but you are after a post-order, so this requires a little extra work.
Here is a post-order traversal using zippers:
(require '[clojure.zip :as z])
(defn dfs-post-order-traversal [zipper]
(loop [loc zipper, a []]
(cond
(z/end? loc)
(conj a (z/node loc))
(z/branch? loc)
(recur (z/next loc) a)
:else
(recur
(z/next loc)
(into
(conj a (z/node loc))
(reverse
(drop
((fnil count [nil]) (z/path (z/next loc)))
(z/path loc))))))))
And the test case:
(dfs-post-order-traversal (z/seq-zip '((a b) (c d))))
=> [a b (a b) c d (c d) ((a b) (c d))]
Now to finish off your request, we need to map tree locations back to their indices:
(defn dfs-post-order-indexing [branch? children root]
(let [pot (dfs-post-order-traversal (z/zipper branch? children conj root))
m (zipmap pot (range))]
(for [n pot] [(m n) n (if (branch? n) (map m (children n)) (list))])))
(dfs-post-order-indexing seq? identity '((a b) (c d)))
=> ([0 a ()]
[1 b ()]
[2 (a b) (0 1)]
[3 c ()]
[4 d ()]
[5 (c d) (3 4)]
[6 ((a b) (c d)) (2 5)])
Something more exotic:
(dfs-post-order-indexing coll? seq [{:a :b :c :d} :e [:f [:g '(:h :i)]]])
=> ([0 :a ()]
[1 :b ()]
[2 [:a :b] (0 1)]
[3 :c ()]
[4 :d ()]
[5 [:c :d] (3 4)]
[6 {:a :b, :c :d} (2 5)]
[7 :e ()]
[8 :f ()]
[9 :g ()]
[10 :h ()]
[11 :i ()]
[12 (:h :i) (10 11)]
[13 [:g (:h :i)] (9 12)]
[14 [:f [:g (:h :i)]] (8 13)]
[15 [{:a :b, :c :d} :e [:f [:g (:h :i)]]] (6 7 14)])
(use '[clojure.walk :only (postwalk)])
(use '[clojure.set :only (map-invert)])
(defn idx [col]
(let [m (map vector
(range)
(let [v (atom [])]
(postwalk (fn [f] (swap! v conj f) f) col)
#v))
rm (map-invert m)]
(into {} (map (fn [[i e]]
[i [e (if (sequential? e)
(mapv rm e)
[])]])
m))))
(idx '((a b) (c d)))
=> {0 [a []],
1 [b []],
2 [(a b) [0 1]],
3 [c []],
4 [d []],
5 [(c d) [3 4]],
6 [((a b) (c d)) [2 5]]}
I have a list [2 3 5] which I want to use to remove items from another list like [1 2 3 4 5], so that I get [1 4].
thanks
Try this:
(let [a [1 2 3 4 5]
b [2 3 5]]
(remove (set b) a))
which returns (1 4).
The remove function, by the way, takes a predicate and a collection, and returns a sequence of the elements that don't satisfy the predicate (a set, in this example).
user=> (use 'clojure.set)
nil
user=> (difference (set [1 2 3 4 5]) (set [2 3 5]))
#{1 4}
Reference:
http://clojure.org/data_structures#toc22
http://clojure.org/api#difference
You can do this yourself with something like:
(def a [2 3 5])
(def b [1 2 3 4 5])
(defn seq-contains?
[coll target] (some #(= target %) coll))
(filter #(not (seq-contains? a %)) b)
; (3 4 5)
A version based on the reducers library could be:
(require '[clojure.core.reducers :as r])
(defn seq-contains?
[coll target]
(some #(= target %) coll))
(defn my-remove
"remove values from seq b that are present in seq a"
[a b]
(into [] (r/filter #(not (seq-contains? b %)) a)))
(my-remove [1 2 3 4 5] [2 3 5] )
; [1 4]
EDIT Added seq-contains? code
Here is my take without using sets;
(defn my-diff-func [X Y]
(reduce #(remove (fn [x] (= x %2)) %1) X Y ))