Add object to a list in clojure and return

151 Views Asked by At

I am new to functional programming and have a use case where I have a list of Books, I want to iterate over it, do some mapping and return a new List. My code

(defn map-book [books]
  ((doseq [x books]
     (let [lst (create-response x)]
       (println "data -> " (json/encode lst))
       (json/encode lst)))))
    

(defn create-response [book]
  (let [updated-book (merge {"book-name" (.getBookName book)
                             "book-page"   (.getBookPageCount book)}]
  updated-book))

when I try to run this, I am able to get json decoded response in terminal due to println but not the json list as a response from the function. have been stucked around for some time on this.

What I want is something like :

[{
        "book-name": "rick boy",
        "book-page": 110

    },
    {
        "book-name": "poor boy",
        "book-page": 124
    }
]

but am getting something like, when I run my unit test:

#object[book_service.book$map_book 0x7915bca3 [book_service.book$map_book@7915bca3]

thanks for any help!

1

There are 1 best solutions below

2
Martin Půda On BEST ANSWER

If you want to return new list (or vector), you should avoid doseq (which is for side effects- for example, printing, and always returns nil) and use map or for instead.

I guess you want to return JSON string for given data and your json library is actually Cheshire:

Dependencies: [cheshire "5.11.0"]

Require in ns: [cheshire.core :as json]

Book class:

public class Book {
    String bookName;
    Long pageCount;

    public Book(String name, Long pages) {
        bookName = name;
        pageCount = pages;
    }

    public String getBookName() {
        return bookName;
    }

    public Long getBookPageCount() {
        return pageCount;
    }
}

Clojure code:

(defn get-book-map [book]
  {"book-name" (.getBookName book)
   "book-page" (.getBookPageCount book)})

(defn encode-books [books]
  (json/encode (map get-book-map books)))

Test:

(encode-books [(Book. "rick boy" 110)
               (Book. "poor boy" 124)])
=> "[{\"book-name\":\"rick boy\",\"book-page\":110},{\"book-name\":\"poor boy\",\"book-page\":124}]"

(json/decode *1)
=> ({"book-name" "rick boy", "book-page" 110} {"book-name" "poor boy", "book-page" 124})