0
votes

I'm very new to Clojure. I want to pass a List<HashMap<String,String>> to a Clojure function in which I want to use the inner HashMaps as regular Clojure maps but I cannot get values from the map with using the :key function (which works fine for a regular Clojure map) I use the into {} function but it does not make what I except it to make. What is what I do wrong? (Note: This is a demostration test code just to see the behaviour)

Java code:

package com.experimental.clojure.java;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.experimental.clojure.test.ConvertTest;

public class Test_Cloj_Convert {
    public static void main(String[] args) {
        List<Map<String, String>> columns = new ArrayList<Map<String, String>>();
        Map<String, String> col1 = new HashMap<String, String>();
        col1.put("name", "ID");
        col1.put("type", "int");
        col1.put("pos", "0");
        Map<String, String> col2 = new HashMap<String, String>();
        col2.put("name", "Name");
        col2.put("type", "string");
        col2.put("pos", "2");
        Map<String, String> col3 = new HashMap<String, String>();
        col3.put("name", "Description");
        col3.put("type", "enum");
        col3.put("pos", "1");
        columns.add(col1);
        columns.add(col2);
        columns.add(col3);

        ConvertTest scripter = new ConvertTest();
        System.out.println(scripter.conv(columns));
    }
}

Clojure code

(ns com.experimental.clojure.test.ConvertTest
  (:gen-class
   :name com.experimental.clojure.test.ConvertTest
   :methods [
             [conv [java.util.List] String]
  ])
  (:import [java.util List] [java.util HashMap])  
)

(defn conv
    [columns]
    (println columns)
    (println (first columns))
    (println (:type (first columns)))
    (println (into {} (first columns)))
    (println (:type (into {} (first columns))))
)

(defn -conv
  [this columns]
  (conv columns)
)

And the (suprising) output

#<ArrayList [{name=ID, type=int, pos=0}, {name=Name, type=string, pos=2}, {name=Description, type=enum, pos=1}]>
#<HashMap {name=ID, type=int, pos=0}>
nil
{name ID, type int, pos 0}
nil
null

What I've excepted for the third println the return the string "int". And in the fourth println it is obvious that the HashMap is not properly converted into Clojure map. Can you help what to do for the successful conversion? (I know I could use the get() function of the HashMap but it would be more comfortable to able to use it as a Clojure map)

2

2 Answers

1
votes

Two issues I see:

  • Your conv function is returning nil, because println is the last statement and that returns nil
  • ":type" is a Clojure keyword which is not equal to the String key "type" - hence the lookups are failing to find the value you want
0
votes

I understand now more and it was asking a silly thing. Sorry for all, but I was under the impression that in Clojure the following two structures are indentical. {"a" 1, "b" 2, "c" 3} and {:a 1, :b 2, :c 3} They are not and I tried to use the wrong method for getting the data from the map. I tried with using (println ((into {} (first columns)) "pos")) and it works fine. I'm sorry for not realizing this sooner.

However, if I may ask again. What is the real difference between them? Right now I only have a vague idea about that.