Passing map parameters to a function in Clojure - clojure

I have the following function:
(defn add-column-2
[catalog columns]
(println "Add-column-2")
(update-in catalog ["streams" (column->tap-stream-id (:v1 columns))]
add-column-to-stream
(:v1 columns)
(:v2 columns)))
In other words, I want that columns parameter as a map so that I can use the parameters v1 and v2 inside the function.
For that purpose, I am calling this function like:
(reduce add-column-2 empty-catalog all-columns)
Where all-columns is a map that contains v1 and v2 keys as you can see from this image:
And empty-catalog is:
(def empty-catalog {"streams" {}})
However, when I am debugging, in the add-column-2 function parameters:
catalog: Comes as expected.
columns: Only map entry with v1 key is passing as you can see from the image below.
The question is, why the v2 key is not passing to the add-column-2 function? How can I pass whole map as a parameter?
P.S. During my investigation, I saw this question however when I try like this, I am still unable to get that v2 key (it returns null).

Related

Modyfing higher order functions output in ClojureScript

I want to create helper function that modifies output returned by higher-order function.
Example of higher-order function:
(def use-meta-sub (make-app-fn (make-sub :meta)))
The problem is that when using this in let like this:
(let [meta-sub (use-meta-sub props :get-me-meta-of-this)])
returns map of key-value pairs like this:
{:key-we-almost-never-need-1 nil
:key-we-almost-never-need-2 nil
:key-we-almost-never-need-3 nil
:key-we-almost-never-need-4 nil
:meta-data {:something-useful "foo"
:more-usefull "bar"
:and-so-on "baz"}}
I would like to target only this :meta-data key
I tried this and some other variations:
(defn use-meta-data-sub [props ctrl]
(:meta-data (use-meta-sub props ctrl))) ;; both with get
It does not work because (I think, that returns lazy sequence and I do not know how to actually firs evaluate it and then extract the key from output).
Is this possible without editing 1st higher-order function, and other two it contains?
(I read all documentation on clojure site and clojure-unraveled, either I do not understand them, or they do not cover this)

In EDN, how can I pass multiple values to tagged element returned from other tagged elements

I have following EDN
{
:test #xyz/getXyz #abc/getAbc #fgh/getFgh "sampleString"
}
In Clojure, I have defined implementation for each of the tagged element which internally calls java functions. I have a requirement in which I need to pass return values of both #abc/getAbc and #fgh/getFgh to #xyz/getXyz as separate parameters.
In my current implementation #fgh/getFgh gets called with "sampleString". And with the output of #fgh/getFgh, #abc/getAbc gets called. And with its output #xyz/getXyz gets called.
My requirement is #xyz/getXyz should get called with return value of both #abc/getAbc and #fgh/getFgh as individual parameters.
Clojure implementation
(defn getXyz [sampleString]
(.getXyz xyzBuilder sampleString)
)
(defn getAbc [sampleString]
(.getAbc abcBuilder sampleString)
)
(defn getFgh [sampleString]
(.getFgh fghBuilder sampleString)
)
(defn custom-readers []
{
'xyz/getXyz getXyz
'xyz/getAbc getAbc
'xyz/getFgh getFgh
}
)
I want to modify getXyz to
(defn getXyz [abcReturnValue fghReturnValue]
(.getXyz xyzBuilder abcReturnValue fghReturnValue)
)
You can't do exactly what you are asking. The tag can only process the following form. That said, you can alter the syntax for your Xyz EDN so that it can support taking a vector of [Abc Fgh] pair.
{:test #xyz/getXyz [#abc/getAbc "sampleString" #fgh/getFgh "sampleString"]}
I'm not sure if you meant that getAbc still needed to take getFgh as input or not. If so, it would be more like:
{:test #xyz/getXyz [#abc/getAbc #fgh/getFgh "sampleString" #fgh/getFgh "sampleString"]}
Now your getXyz tagged reader will receive a vector of Abc and Fgh. So you'll need to change your code to grab the elements from inside the vector, something like that:
(defn getXyz [[abcReturnValue fghReturnValue]]
(.getXyz xyzBuilder abcReturnValue fghReturnValue))
This uses destructuring syntax (notice that the arguments are wrapped in an extra pair of bracket), but you could use first and second if you wanted instead, or any other way.

Clojure get the value inside a map

How do I get openid.claimed_id or any other field in a map like this?
:openid.claimed_id won't work.
{"openid.response_nonce" "2015-07-25T09:31:45ZXrcrR0Lk35St5ESZQ0tg40PbBXU=", "openid.identity" "http://steamcommunity.com/openid/id/xxx", "openid.ns" "http://specs.openid.net/auth/2.0", "openid.op_endpoint" "https://steamcommunity.com/openid/login", "openid.mode" "id_res", "openid.sig" "zuiyNzf/QLP9Ci/czElIo1Z3nE0=", "openid.signed" "signed,op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle", "openid.assoc_handle" "1234567890", "openid.claimed_id" "http://steamcommunity.com/openid/id/xxx", "openid.return_to" "http://localhost:3000/resp"}
The keys in your map are Strings and not Keywords.
You can either use:
(get m "openid.claimed_id")
or you can first convert the String keys to Keywords and then lookup based on a Keyword:
(:openid.claimed_id (clojure.walk/keywordize-keys m))
Since a map is also a function that can do lookup on itself, the simplest way to do this is
(m "openid.claimed_id")
with m being your map.

Using list values to form single redis mget

I have a clojure list
("mykey:1" "mykey:2" "mykey:3")
I want to use redis mget to fetch values of all keys
(mget mykey:1 mykey:2 mykey:3)
I'm using the wonderful Carmine library.. I don't have any problem with it at all but when I try to use the list in a function
(defn get-keys
[k]
(mget k))
The key k actually includes the brackets too, since it's a list. Doing:
(mget (map #(%) k))
gets me nowhere either.
How do I now split them into individual keys so I can pass it to mget? is that possible?
Thanks
When you have a collection that contains values you want to use as the arguments to a function, you should use apply.
(def args '("mykey:1" "mykey:2" "mykey:3"))
(apply mget args)
; is equivalent to the call
(mget "mykey:1" "mykey:2" "mykey:3")

Constructing a map from a vector in Clojure

I have a vector that looks like this:
["Config" "{}" "Auth" "{}" "Other" "{}"]
I'd like to take each key value pair and turn it into the following map:
{"Config" "{}", "Auth" "{}", "Other" "{}"}
How can I do this with Clojure? Is there a built in function that does this?
Use apply to apply the map constructor of desired type to the vector, ie :
(apply hash-map ["Config" "{}" "Auth" "{}" "Other" "{}"])
edit
According to this answer you can get different map types depending on the way you evaluate {}, so use the map constructor suitable to your needs.
edit
Looking at this the different object types returned by literal {} appears to be a bug.