gini09
gini09

Reputation: 379

How to convert a list into JSON in Clojure?

I have a list like below (some sort of ranking data, list is in order):

'(John Kelly Daniel)

and want to convert it into JSON like below:

[{"rank":1, "name":"John"},{"rank":2, "name":"Kelly"},{"rank":3, "name":"Daniel"}]

What would be the easiest and simplest way of doing this using json/write-str at the end?

Upvotes: 1

Views: 1253

Answers (2)

MicSokoli
MicSokoli

Reputation: 841

You can do this using mapv to create the maps with one rank and one name, and the library cheshire to convert the vector to json. It is isn't considered idiomatic to use lists for your data in Clojure, so I suggest you use a vector instead.

(ns rankifier.core
  (:require [cheshire.core :refer [generate-string]]))

(defn rankify [names]
  (mapv #(hash-map :name %1 :rank %2)
        names
        (range 1 (inc (count names)))))

In the namespace declaration we only require the function generate-string of cheshire. Then we define the function rankify, which takes a vector names as its argument and returns a vector of hash maps, each containing a name and a rank, where the rank for the first name is 1, for the second name it is 2 and so on, for all the given names.

We can try it out like this, using the thread-first macro:

rankifier.core> (-> ["John" "Kelly" "Daniel"]
                    rankify
                    generate-string)
"[{\"name\":\"John\",\"rank\":1},{\"name\":\"Kelly\",\"rank\":2},    {\"name\":\"Daniel\",\"rank\":3}]"

If we didn't convert it to json, the result would look like this:

rankifier.core> (rankify ["John" "Kelly" "Daniel"])
[{:name "John", :rank 1} {:name "Kelly", :rank 2} {:name "Daniel", :rank 3}]

This works for any number of names:

(rankify ["John" "Kelly" "Daniel" "Maria" "Billy" "Amy"])
[{:name "John", :rank 1}
 {:name "Kelly", :rank 2}
 {:name "Daniel", :rank 3}
 {:name "Maria", :rank 4}
 {:name "Billy", :rank 5}
 {:name "Amy", :rank 6}]

Upvotes: 1

Édipo Féderle
Édipo Féderle

Reputation: 4257

As a complement for @leetwinski answer (and using their code)

(ns some-thing.core
  (:require [cheshire.core :refer :all]))

(def names '(John Kelly Daniel))

(defn add-rank [data]
  (map-indexed #(hash-map :rank (inc %1) :name (str %2)) data))

(-> names
    add-rank
    generate-string)

Upvotes: 4

Related Questions