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

时间:2013-04-15 14:48:42

标签: clojure

如何将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库。

根据documentationadd-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地图。

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

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

(map name (apply concat data))

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

那么,我怎样才能做到这一点? 我是否只需编写大量if-not块来自己构建属性?

由于

4 个答案:

答案 0 :(得分:8)

这应该可以解决问题:

(map name (apply concat data))

地图可以被视为一系列键值对,而这些键值对又表示为2个元素的数组。我们将这些对连接起来,然后我们从关键字和字符串中提取名称(对于字符串,这不做任何事情,对于关键字,它返回没有':'的位)。

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

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

答案 1 :(得分:2)

你可以使用vector来获得随机访问的数组:

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

答案 2 :(得分:2)

您可以尝试以下方法:

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

;; which returns ("starks" "Winter is coming" "Lannisters" "Hear me roar")

答案 3 :(得分:2)

(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函数更受限制,并且不接受变量参数列表。