1

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?

1
  • 1
    something like this: (map-indexed #(hash-map :rank (inc %1) :name (str %2)) '(John Kelly Daniel)), and then pass it to json/write-string but i advice you to read the language basics first Commented Jan 16, 2017 at 8:12

2 Answers 2

4

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.