【问题标题】:Convert map keys and values to string array将映射键和值转换为字符串数组
【发布时间】:2013-04-17 02:19:07
【问题描述】:

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

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

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

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

Marius Danila 的回答让我快到了。

在做

(map name (apply concat data))

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

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

谢谢

【问题讨论】:

    标签: clojure


    【解决方案1】:

    这应该可以解决问题:

    (map name (apply concat data))
    

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

    根据您发布的代码,我猜您会这样使用:

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

    【讨论】:

    • 您好,谢谢!这几乎让我到了那里,但我在字符串周围有一个大括号.. 像这样:("starks" "Winter is coming" "Lannisters" "Hear me roar") - 尝试转换为字符串并替换它没有按预期工作.. 我该如何摆脱大括号?我只需要它作为一个字符串,例如
    • @LocustHorde 好的,我已经更新了我的答案。我希望这就是你要找的。​​span>
    • 嗨,对不起,我可能无法正确通信,我需要字符串数组,键和它们各自的值彼此相邻..我会更新问题..非常感谢.
    • 实际上,再想一想,我也许可以使用这个,让我试试,然后请回来。谢谢。
    • 好的,所以我给了它最后一枪:)
    【解决方案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 函数受到更多限制,根本不接受可变参数列表。

    【讨论】:

    • 哦,这很有意义!非常感谢,将修改我的代码以反映这一点。再次感谢!
    • 是的,效果很好,谢谢!我发誓我可以同时添加几个属性.. 但显然我在想别的东西。再次感谢!
    【解决方案3】:

    您可以使用向量来进行随机访问:

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

    【讨论】:

      【解决方案4】:

      您可以尝试以下方法:

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

      【讨论】:

      • 嗨,谢谢,这给出了与 Marius Danila 的回答相同的结果。这个问题的最新答案告诉我,该函数实际上并没有超过 4 个参数。我发誓我认为我可以向它传递任意数量的参数!不过谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      • 2013-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多