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}]
(map-indexed #(hash-map :rank (inc %1) :name (str %2)) '(John Kelly Daniel)), and then pass it tojson/write-stringbut i advice you to read the language basics first