Clojure需要花费更多时间

时间:2013-09-06 14:54:56

标签: clojure

Clojure在下面实施take-while-and-n-more的惯用方法是什么:

=> (take-while-and-n-more #(<= % 3)  1 (range 10))
(0 1 2 3 4)

我的尝试是:

(defn take-while-and-n-more [pred n coll]
  (let
      [take-while-result (take-while pred coll)
       n0 (count take-while-result)] 
    (concat
     take-while-result
     (into [] (take n (drop n0 coll))))))

3 个答案:

答案 0 :(得分:9)

我会使用split-with,这相当于获取相同参数的take-while和drop-while的结果:

(defn take-while-and-n-more [pred n coll]
    (let [[head tail] (split-with pred coll)]
         (concat head (take n tail))))

答案 1 :(得分:3)

另一种方式:

(defn take-while-and-n-more [pred n coll]
  (let [[a b] (split-with pred coll)]
    (concat a (take n b)))) 

答案 2 :(得分:1)

以下代码是Clojures take-while的修改版本。其中Clojures take-while返回nil作为默认情况(当谓词不匹配时),此谓词调用take以在谓词失败后获取其他项。

请注意,与使用split-with的版本不同,此版本仅遍历序列一次。

(defn take-while-and-n-more
  [pred n coll]
  (lazy-seq
   (when-let [s (seq coll)]
     (if (pred (first s))
       (cons (first s) (take-while-and-n-more pred n (rest s)))
       (take n s)))))