【问题标题】:What's the right way to create a Clojure function that returns a new sequence based on another sequence?创建基于另一个序列返回新序列的 Clojure 函数的正确方法是什么?
【发布时间】:2012-04-20 10:13:30
【问题描述】:

为什么必须在 get-word-ids 中使用“first”,正确的做法是什么?

(defn parts-of-speech []
  (lazy-seq (. POS values)))

(defn index-words [pos]
  (iterator-seq (. dict getIndexWordIterator pos)))

(defn word-ids [word]
  (lazy-seq (. word getWordIDs)))

(defn get-word [word-id]
  (. dict getWord word-id))

(defn get-index-words []
  (lazy-seq (map index-words (parts-of-speech))))

(defn get-word-ids []
  (lazy-seq (map word-ids (first (get-index-words)))))

;; this works, but why do you have to use "first" in get-word-ids?
(doseq [word-id (get-word-ids)]
  (println word-id))

【问题讨论】:

  • 你用错了lazy-seq,有一个成语你必须尊重。但主要是,这是低级的东西,“正确的方法”是结合现有的核心功能如mapfilterfor等来实现你想要的。

标签: clojure


【解决方案1】:

简短的回答:删除所有对lazy-seq 的引用。

至于您最初的问题,即使它不是惰性序列的惯用用法,也值得解释一下。您必须首先使用,因为 get-word-ids 函数返回一个带有一个条目的惰性序列。该条目是您正在寻找的惰性序列。

看起来像这样

( (word1 word2 word3) )

所以首先返回你想要的序列:

(word1 word2 word3)


很有可能您将使用lazy-seq 的唯一时间将是这种模式:
(lazy-seq (cons :something (function-call :produces :the :next :element)))

我从未见过任何其他模式中使用过惰性序列。 lazy-seq 的目的是生成新的原始数据序列。如果存在生成数据的代码,那么使用iterate mapfor 之类的东西来生成惰性序列几乎总是更好。

【讨论】:

  • 谢谢你,亚瑟。那么,既然 Java 方法返回一个迭代器,那么在索引词中是否正确使用了 iterator-seq?
【解决方案2】:

这似乎是错误的:

(defn get-index-words []
  (lazy-seq (map index-words (parts-of-speech))))

(index-words pos) 返回一个序列。这就是为什么您需要在 get-word-ids 中使用(第一个)。

map 也已经是惰性的了,所以没有必要在惰性序列中包装 (map ...),如果映射 不是 懒惰。如果您阅读更多关于 clojure 中(惰性)序列的内容,它可能会很有用。

【讨论】:

    猜你喜欢
    • 2018-06-16
    • 1970-01-01
    • 2019-04-14
    • 2019-01-27
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    相关资源
    最近更新 更多