文件中行的集合

3
这应该是一个简单的问题,但我已经花了几个小时,仍然不明白如何在Clojure中正确地使用集合。我试图读取一个文件并将每一行存储在一个集合中。 以下是我的代码。
(def dictionary #{})
  ;(conj dictionary "hi")
  (defn readDictionary []
    (doseq [line (clojure.string/split-lines 
       (slurp "C:\\Working\\Other\\dictionary.txt"))]
      (println line)
      (conj dictionary line)))
  (readDictionary)

  (println dictionary)

我可以将字符串“hi”附加到集合中,并且在doseq内打印出每行内容,但当我打印出集合时,它最终为空。

我非常熟悉面向对象编程,但函数式编程对我来说是一件新事物。

2个回答

6
问题并不在于集合本身。问题在于`conj`和大多数核心库一样,没有副作用。因此,表达式:
(conj dictionary line)

...evaluates为添加了linedictionary,使dictionary(和line)保持不变。因此,doseq生成一个包含一行的集合序列。

调用:

(readDictionary)

...评估了这个单成员集合的序列,然后丢弃它,因为它没有与任何东西绑定。 因此,调用没有任何实际效果

我认为你想要像这样的东西(未经测试):

(defn readDictionary [file-name]
  (into #{} (clojure.string/split-lines (slurp file-name))))

(def dictionary (readDictionary "C:\\Working\\Other\\dictionary.txt"))

(doseq [line dictionary] (println line))

在Clojure中,你需要习惯使用纯函数(无副作用)操作不可变/持久化数据结构。

谢谢!那是一个非常有帮助的解释。有没有关于函数式编程的好入门教程?我一直不知道该搜索什么。 - qzcx
2
我从《The Little Schemer》开始学习——这是一本介绍Scheme方言中递归和列表基础的教材。至于Clojure:Try Clojure让你在浏览器中使用REPL;4Clojure提供了一个阶梯式问题,从初级到困难(还有一些问题要解决...grrrrrr)。官方文档有一个入门指南,其中提到了这些工具和其他工具。享受吧! - Thumbnail
2
@qzcx... 当你完成了这些工作之后,你会理解为什么KobbyPemson的解决方案比我们的更好。 - Thumbnail

1
从文件中读取行并存入集合中。
(with-open [rdr (clojure.java.io/reader "C:\\Working\\Other\\dictionary.txt")]
   (set (line-seq rdr)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接