7

如何将一个clojure map转换成字符串,几乎是键值对,如下图:

Clojure 数据:

(def data { :starks "Winter is coming" :Lannisters "Hear me roar" })

我想将以上内容转换为

"starks" "winter is coming" "Lannisters" "hear me roar"

我不想要任何标识符/分隔符,但显然"starks"应该始终跟随"winter is coming"

我试过这个:

(str (keys data) (vals data))

哪个输出:

"(:starks :Lannisters)(\"Winter is coming\" \"Hear me roar\")"

这根本不是我想要的……

  • 地图数据键和值并不总是相同,因此需要通用
  • 总是只有一个级别,例如,该值将不包含嵌套映射等。

编辑

我实际上正在尝试做的事情:

我正在尝试用 clojure索引几千个Neo4j节点。为了帮助我完成这项任务,我正在使用Neocons Clojure neo4j库。

根据文档add-to-index接受属性和值如下:

(nn/add-to-index (:id node) (:name idx) "username" "joe")))

也就是说,在我上面的例子中,看起来像

(nn/add-to-index (:id node) (:name idx) "starks" "winter is coming" "Lannisters" "Hear me roar")))

现在,我有了我的节点,我可以使用它访问节点属性,(:data node)这给了我一个 clojure 映射。

该属性因节点而异,因此我试图弄清楚如何以它理解的方式将该映射传递给库。

Marius Danila的回答让我几乎到了那里。

正在做

(map name (apply concat data))

仍然抱怨第三个参数,因为它在结果周围有大括号。

那么,我该如何实现呢?我是否只需要编写很多if-not块来自己构建属性?

谢谢

4

4 回答 4

8

这应该可以解决问题:

(map name (apply concat data))

可以将映射视为一系列键值对,而这些键值对又表示为 2 个元素的数组。我们将这些对连接起来,然后从关键字和字符串中提取名称(对于字符串,它什么都不做,对于关键字,它返回不带':'的位)。

从您发布的代码中,我猜您会像这样使用它:

(apply nn/add-to-index (list* (:id node) (:name idx) (map name (apply concat data))))
于 2013-04-15T15:03:15.793 回答
2

您可以使用向量来获得像随机访问这样的数组:

=> (def v (vec (map name (apply concat data))))
=> (v 0)
;"starks"
=> (v 1)
;"Winter is coming"
于 2013-04-15T16:09:31.140 回答
2

您可以尝试以下方法:

=> (interleave (map name (keys data)) (vals data))

;; which returns ("starks" "Winter is coming" "Lannisters" "Hear me roar")
于 2013-04-16T06:08:33.570 回答
2

(nn/add-to-index ...)函数只接受四个参数。节点、索引和一个键/值对。因此,您也可以像这样循环遍历数据。

(doseq [[k v] data]
  (nn/add-to-index (:id node) (:name idx) (name k) (clojure.string/lower-case v))))

strClojure 中的函数不同,该add-to-index函数受到更多限制,根本不接受可变参数列表。

于 2013-04-16T18:19:07.983 回答