7

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))))))
4

3 回答 3

10

我会使用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))))
于 2013-09-06T15:05:13.057 回答
3

还有一种方式:

(defn take-while-and-n-more [pred n coll]
  (let [[a b] (split-with pred coll)]
    (concat a (take n b)))) 
于 2013-09-06T15:05:26.683 回答
2

以下代码是 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)))))
于 2013-09-06T15:01:45.017 回答