关于Clojure:将映射键和值转换为字符串数组

Convert map keys and values to string array

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

Clojure数据:

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

我想将以上转换为

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

我不希望在它们之间使用任何标识符/定界符,但显然"starks"之后应始终跟随"winter is coming"

我尝试了这个:

1
(str (keys data) (vals data))

输出以下内容:

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

这根本不是我想要的...

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

编辑

我实际上正在尝试做的是:

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

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

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

在我上面的情况下,看起来像

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

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

节点之间的属性差异很大,因此我试图找出如何以其理解的方式将该映射传递给库。

Marius Danila的回答使我快到了。

在做

1
(map name (apply concat data))

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

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

谢谢


这应该可以解决问题:

1
(map name (apply concat data))

可以将映射视为一系列键值对,依次将其表示为2个元素的数组。 我们将对连接在一起,然后从关键字和字符串中提取名称(对于字符串,它不执行任何操作,对于关键字,它返回不带':'的位)。

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

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


(nn/add-to-index ...)函数仅接受四个参数。 节点,索引和一个键/值对。 因此,您也需要遍历数据。

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

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


您可以尝试以下方法:

1
2
3
=> (interleave (map name (keys data)) (vals data))

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


您可以使用vector像随机访问一样具有数组:

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