0

I'm a newbie in clojure, so please bear with me.

Writing a macro as so:

 `(let [query#   (:query-params ~'+compojure-api-request+)
        options# (select-keys query# [:sort-by :from :to])])

First line of the let block destructures a query-params from http request - which produces this structure:

{sort-by billing-account/name, from 0, to 10, payment-due , payment-method , search }

And the trouble is with the second line - it returns an empty map when I use select-keys, however when I say for example (first query#) - the output looks like this: [sort-by billing-account/name]

Could anyone please explain why the select-keys does not work?

P.S. Tried (get query# :from) & (:from query#) - no luck there as well.

UPD

Keys were strings, not keywords - therefore using strings as keys works just fine.

Alex Miller
  • 65,227
  • 26
  • 112
  • 160
Sasha
  • 1,100
  • 2
  • 12
  • 23

2 Answers2

1

By the way, you can also destructure string keys with :strs:

(let [m {"sort-by" "billing-account/name", 
         "from" "0",
         "to" "10", 
         "payment-due" nil, 
         "payment-method", "search"}
      {:strs [sort-by from to payment-due payment-method]} m]
  (println sort-by from to payment-due payment-method))

;;=> billing-account/name 0 10 nil search     

See https://clojure.org/guides/destructuring for a full description of the destructuring syntax.

Alex Miller
  • 65,227
  • 26
  • 112
  • 160
0

I think you are confused by the differences between keywords, symbols and strings. In your comment you say that they're symbols, but in your edit you say they're strings.

You should read up on the difference:

The idiomatic thing is to usually prefer using keywords as map keys, although stuff that comes from the internet (json, http headers, etc) is sometimes all strings.

To answer your question directly, the keys passed to select-keys need to be equal (using the = function) to the ones in the map, so in this case they need to be the same type.

;; For example

(select-keys {'foo 1 'bar 2} ['foo]) ;=> {foo 1}

(select-keys {:foo 1 :bar 2} [:foo]) ;=> {:foo 1}

(select-keys {"foo" 1 "bar" 2} ["foo"]) ;=> {"foo" 1}

Also I question the need for this to be a macro, is there a reason that a plain function won't work?

Community
  • 1
  • 1
madstap
  • 1,542
  • 10
  • 21
  • Hi, thanks you for the answer, no not confused, mistype, I tried editing the comment, but it didn't let me :-( – Sasha Feb 02 '17 at 08:58