Clojure - Convert data from one form to another [closed] - clojure

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to convert the following data:
({"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]})
into
({:name "testdb"} {:name "mydb"})
I am unable to figure how can i do this neatly in a clojure way.

When you want to make multiple maps all with the same keys, partially applying zipmap works pretty neatly:
(defn to-maps [{:strs [columns values]}]
(map (partial zipmap (map keyword columns)) values))
Examples:
(to-maps {"name" "databases", "columns" ["name"], "values" [["testdb"] ["mydb"]]})
;;=> ({:name "testdb"} {:name "mydb"})
(to-maps {"name" "databases",
"columns" ["name", "connectionstring"],
"values" [["testdb", "foo"] ["mydb", "bar"]]})
;;=> ({:connectionstring "foo", :name "testdb"} {:connectionstring "bar", :name "mydb"})

Related

constructing a clojure function that returns elements [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Hi im new to clojure and wanted to create a function that returns a list with three elements:
the first element is a string
the second element is a vector y (this should contain three keywords)
the last element is a number
My function code so far:
(defn make-list [x,y,z]
(str)
[:y1 :y2 :y3]
z)
Assuming that the elements that you want to build the list with are your arguments, x, y and z; and that you are going to provide the right element types (eg. x will be a string, y will be the list of 3 keywords, and z will be a number, you can simply call the function list:
$ clj
Clojure 1.10.1
user=> (list "hello" [:a :b :c] 42)
("hello" [:a :b :c] 42)
In your code, what's happening is that you are providing the 3 arguments and the function is evaluating the values you passed, and the last value is simply returned:
(defn make-list [x,y,z]
(str) ;; this creates an empty string that is not bound to a name, will be discarded
[:y1 :y2 :y3] ;; this creates a vector with 3 keywords, also will be lost, same as above
z) ;; z is the last value being evaluated, will be returned
like this:
user=> (make-list "unused" [:values :not :used :either] 99)
99

If we generalize clojure function juxt to juxe, that is juxe returns a hash map instead of vector, will this function juxe be useful? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In some functional programming books, they define tuple as the form [a b c] and entity as the form {:a x :b y :c z}.
If we take the t in juxt as the idea of tuple, can we have a higher order function name juxe with e as the idea of entity?
Therefore, the behavior of juxe will be like
((juxe :a a :b b :c c) x) => {:a (a x) :b (b x) :c (c x)}
Will this function juxe be useful?
Some background ideas of this question. I consider there are three types of higher order functions in Clojure:
type 1: higher order template functions
map, filter, reduce, take-nth, group-by
type 2: higher order decorate functions
partial, comp, juxt
type 3: #( ... %1 %2)
I usually uses type 3 to achieve many things that type 2 can also do because I feel the readability of type 3 is better. However, I feel the functions of type 2 really expand my imagination and for me, it is the real value of them.
Also, the recently release of datomic query now support to return set of entity. Originally it can only return set of tuple.
(defn juxe [& kf-pairs]
(let [pairs (partition 2 kf-pairs)
[ks fs] (apply mapv vector pairs)]
(fn [x] (zipmap ks (map #(% x) fs)))))
For example,
=> ((juxe :a inc :b dec :c -) 99)
{:a 100, :b 98, :c -99}

Clojure - update hashmaps inside vectors [duplicate]

This question already has answers here:
How can I update a vector item in Clojure?
(3 answers)
Closed 4 years ago.
Let's suppose I have the following vector
[{:id "1" :type "type"}, {:id "2" :type "another-type"}]
And I want to write a function that updates a hashmap, depending on it's id.
(defn update
[vector id value]
....)
And the result would be:
(update vector "1" "value")
[{:id "1" :type "type" :new-key ["value"]}, {:id "2" :type "another-type"}]
What's the most idiomatic way of performing this change?
(mapv
(fn [m]
(if (= "1" (:id m)) (assoc m :new-key ["value"]) m))
vector)

How can I traverse through my result? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
This is what I currently have:
{:total-pages 1, :total-results 1, :items [{:item-atributes {:title Tolkien Calendar 2017, :product-group Book, :manufacturer Harper Voyager, :author J. R.
R. Tolkien}, :SalesRank 12016, :item-links [{:description Technical Details, :url https://www.amazon.com/Tolkien-Calendar-2017-J-R/dp/tech-data/0062566938
%3FSubscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D215401-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0062566938} {:description Ad
d To Baby Registry, :url https://www.amazon.com/gp/registry/baby/add-item.html%3Fasin.0%3D0062566938%26SubscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D215401
-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0062566938} {:description Add To Wedding Registry, :url https://www.amazon.com/gp/r
egistry/wedding/add-item.html%3Fasin.0%3D0062566938%26SubscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D215401-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D3
86001%26creativeASIN%3D0062566938} {:description Add To Wishlist, :url https://www.amazon.com/gp/registry/wishlist/add-item.html%3Fasin.0%3D0062566938%26Su
bscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D215401-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0062566938} {:description Tell A
Friend, :url https://www.amazon.com/gp/pdp/taf/0062566938%3FSubscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D215401-20%26linkCode%3Dxm2%26camp%3D2025%26creati
ve%3D386001%26creativeASIN%3D0062566938} {:description All Customer Reviews, :url https://www.amazon.com/review/product/0062566938%3FSubscriptionId%3DAKIAI
6FVBZ4SCQ3VMGCQ%26tag%3D215401-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D0062566938} {:description All Offers, :url https://ww
w.amazon.com/gp/offer-listing/0062566938%3FSubscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D215401-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26cre
ativeASIN%3D0062566938}], :detail-page-url https://www.amazon.com/Tolkien-Calendar-2017-J-R/dp/0062566938%3FSubscriptionId%3DAKIAI6FVBZ4SCQ3VMGCQ%26tag%3D2
15401-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0062566938, :asin 0062566938}]}
I got this from a result and wanted to traverse through it.
No, that's not XML. You can use get-in to traverse your nested structure.
As #jmargolistvt said, you have a Clojure data structure (nested maps & arrays), not xml.
Also, next time please print using the prn instead of println or similar, as it is important to keep the double-quote chars around strings like "Harper Voyager".
I simplified the data a bit, and have this:
(ns clj.core
(:require
[tupelo.core :as t]
[clojure.pprint :as pp]
)
(:gen-class))
(t/refer-tupelo)
(def data
{:total-pages 1, :total-results 1, :items
[ {:item-atributes
{:title "Tolkien Calendar 2017", :product-group "Book",
:manufacturer "Harper Voyager"
:author "J. R. R. Tolkien" }, :SalesRank 12016, :item-links [{:description "Technical Details" } ]
} ] } )
(pp/pprint data)
(defn -main [& args]
)
which yields:
~/clj > lein run
{:total-pages 1,
:total-results 1,
:items
[{:item-atributes
{:title "Tolkien Calendar 2017",
:product-group "Book",
:manufacturer "Harper Voyager",
:author "J. R. R. Tolkien"},
:SalesRank 12016,
:item-links [{:description "Technical Details"}]}]}
At this point, you can add
(newline)
(doseq [item (data :items) ]
(newline)
(pp/pprint item)
(newline)
(spyx (item :SalesRank))
(spyx (get-in item [:item-atributes :title])))
to get:
{:item-atributes
{:title "Tolkien Calendar 2017",
:product-group "Book",
:manufacturer "Harper Voyager",
:author "J. R. R. Tolkien"},
:SalesRank 12016,
:item-links [{:description "Technical Details"}]}
(item :SalesRank) => 12016
(get-in item [:item-atributes :title]) => "Tolkien Calendar 2017"
Your project.clj must include this to make the (spyx ...) part work:
:dependencies [
[tupelo "0.9.9"] ...

Adding a function to keyword values [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
i have a map structure like this...
{"email#gmail.com"{:email "email#gmail.com", :password "pass"},
"email2#yahoo.com"{:email "email2#yahoo.com", :password "pass2"},
"email3#yahoo.com"{:email "email3#yahoo.com", :password "pass3"},
"email4#gmail.com"{:email "email4#gmail.com", :password "pass4"}}
how can i add a function to all values in refering to :password keyword?my function has a parameter that accepts only strings...this is what i tried but couldn't got around it...
(update-in mymap [:password] (myfunction "here were suppose to be values from :password keyword"))
You should update each line separately and accumulate, so iterate with reduce over the list, then for each element update-in the password key and assoc the resulting row to the result.
(reduce (fn[result row]
(assoc result
(first row) ;;email
(update-in (second row)
[:password]
(fn[pass] ..do something..))))
{}
mymap)
(reduce-kv (fn [result k cfg-map]
(assoc result
k (update-in cfg-map [:password] your-fn)))
{} your-ds)
or
(into {} (mapv #(update-in % [1 :password] your-fn) your-ds))