9

除了 loop .. recur,最好的 Clojure 构造是什么,以便在遍历序列序列 (sos) 时,如果找到结果,处理可以停止?

以下是详细信息:

我有一个从 clojure-csv 返回的惰性序列,一个 sos。

在 sos 中的每个序列中的给定位置(索引)处都有一个值。

我一直在每个序列中查看该位置,直到找到该值或到达 sos 的结尾。

如果找到值,我想停止处理 sos。

我唯一能想到的是使用 for with when 和 an into 来保留匹配,但是序列处理不会停止,或者使用过滤器。

但是,我相信我可以使用更好的东西,但我不知道那会是什么。

谢谢。

4

5 回答 5

9

对于此类任务,我更喜欢花点时间,如果密钥位于固定索引处,则 nth 可以匹配它。

(take-while #(not= (nth % index) key) sos)

user> (def sos [[1 2 3] [4 5 6] [7 8 9] [10 11 12]])
#'user/sos
user> (take-while #(not= (nth %  2) 9) sos)
([1 2 3] [4 5 6])

然后,您可以将您的处理功能映射到结果序列上。

于 2012-08-08T15:10:46.437 回答
5

这个怎么样?

(defn find-first [pred col]
  (first (filter pred col)))

然后你可以这样做作为一个例子:

(find-first #(< % 5) coll)

您应该能够制作一个适用于一系列序列的谓词。

user=> (defn find-first [pred col]
  (first (filter pred col)))
#'user/find-first
user=> (find-first #(> % 10) '(1 5 8 2 15 20 31 5 1))
15
于 2012-08-08T14:26:22.907 回答
4

forwith:while可以像这样使用:

(for [s sos :while (not (= (nth s index) val))]  
     s) ;;or do something with s
于 2012-08-08T15:58:35.987 回答
1

当只是搜索第一次出现时,我会使用drop-while. 确实,filter将处理整个序列这是无用的。(如果你想使用无限序列怎么办?)

编辑:不要考虑到这一点。实际上,filter返回一个惰性序列。

(defn find-first
  [pred coll]
  (first (drop-while #(not (pred %)) coll))
于 2012-08-08T14:49:00.503 回答
1

我认为some很适合这个目的。

(pred x)“返回任何xin的第一个逻辑真值coll,否则返回 nil。一个常见的习惯用法是使用集合作为 pred,例如这将返回:fredif :fredis in the sequence,否则返回 nil: (some #{:fred} coll)

于 2015-06-10T23:51:15.160 回答