将映射键和值转换为字符串数组



如何将clojure映射转换为字符串,几乎是键值对,如下所示:

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")))

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

每个节点的属性差异很大,所以我试图弄清楚如何以它理解的方式将映射传递给库。。

马里乌斯·丹妮拉的回答使我几乎达到目的。

进行

(map name (apply concat data))

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

那么,我该如何做到这一点呢?我只需要写大量的if-not块就可以自己构造属性吗?

感谢

这应该可以做到:

(map name (apply concat data))

映射可以被视为键值对的序列,这些键值对又表示为2个元素的数组。我们将这些对连接起来,然后从关键字和字符串中提取名称(对于字符串,这不起任何作用,对于关键字,它返回不带":"的位(。

从你发布的代码来看,我猜你会这样使用:

(apply nn/add-to-index (list* (:id node) (:name idx) (map name (apply concat data))))

(nn/add-to-index ...)函数只接受四个参数。节点、索引和一个键/值对。所以你的数据循环太多了。

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

与Clojure中的str函数不同,add-to-index函数更受限制,并且不接受变量参数列表。

您可以使用向量进行类似数组的随机访问:

=> (def v (vec (map name (apply concat data))))
=> (v 0)
;"starks"
=> (v 1)
;"Winter is coming"

您可以尝试以下操作:

=> (interleave (map name (keys data)) (vals data))
;; which returns ("starks" "Winter is coming" "Lannisters" "Hear me roar")

最新更新