遍历clojure中对象的PersistentVector

Posted

技术标签:

【中文标题】遍历clojure中对象的PersistentVector【英文标题】:iterate over PersistentVector of objects in clojure 【发布时间】:2021-05-01 22:32:17 【问题描述】:

我是 Clojure 的新手,我正在尝试迭代对象的 PersistentVector,当我在日志中打印时,它如下所示。

[name John, email john@example.com name Peter, email peter@example.com]

当我打印(输入 myData)时,它告诉我它的类型是 clojure.lang.PersistentVector

我必须遍历这个向量,一次从其中的每个对象中提取电子邮件并调用另一个函数。

它看起来很简单,我查看了很多示例和问题,但似乎没有什么对我有用:(

谢谢。

【问题讨论】:

【参考方案1】:

这里有几个选项:

如果您不关心对象(Clojure 中的“地图”)并且只想收集电子邮件并对其应用函数,您可以创建一个简单的函数来将电子邮件提取到另一个集合中,然后对电子邮件集合使用任何函数:

(def items
  ["name" "John", "email" "john@example.com" "name" "Peter", "email" "peter@example.com"])

(defn get-email [m]
  (get m "email"))

(mapv get-email items)
;; returns: ["john@example.com", "peter@example.com"]

您可以使用函数组合来创建一个函数,该函数将获取电子邮件的结果变为大写(使用upper-case from clojure.string):(注意comp中的排序):

(mapv (comp clojure.string/upper-case get-email) items)
;; returns ["JOHN@EXAMPLE.COM" "PETER@EXAMPLE.COM"]

如果您想获得类似的收藏但更新了电子邮件字段,您可以使用update-in

(mapv (fn [m] (update-in m ["email"] clojure.string/upper-case)) items)
;; Applies `upper-case` to the "email" path of each map identified by `m`.
;; returns: ["name" "John", "email" "JOHN@EXAMPLE.COM" "name" "Peter", "email" "PETER@EXAMPLE.COM"]

使用其他技术(匿名函数、strs 解构)有更优雅的方法来完成相同的工作,但我认为如果您是 Clojure 新手,上述方法更容易理解。

【讨论】:

以上是关于遍历clojure中对象的PersistentVector的主要内容,如果未能解决你的问题,请参考以下文章

通过 Clojure 中的集合进行递归的惯用方式

如何在 Clojure 中递归展平任意嵌套的向量和映射?

测试列表是不是包含 Clojure 中的特定值

初始化 Java 对象的 Clojure 惯用方法

Clojure 中函数的类型提示

预售┃Scala与Clojure函数式编程模式:Java虚拟机高效编程