Clojure 谓词为true的集合中除最后一个元素外的所有元素的序列
我在编写优雅的Clojure 谓词为true的集合中除最后一个元素外的所有元素的序列,clojure,Clojure,我在编写优雅的drop last by或butlast by函数时遇到问题 (drop-last-by odd? [2 1 9 4 7 7 3]) ; => (2 1 9 4) (drop-last-by odd? [2 4]) ; => (2 4) (drop-last-by odd? [9]) ; => () 到目前为止,我所做的工作很有效,但似乎有点笨拙,我想知道是否可以只用两三行就完成 (defn drop-last-by [pred coll] (let
drop last by
或butlast by
函数时遇到问题
(drop-last-by odd? [2 1 9 4 7 7 3]) ; => (2 1 9 4)
(drop-last-by odd? [2 4]) ; => (2 4)
(drop-last-by odd? [9]) ; => ()
到目前为止,我所做的工作很有效,但似乎有点笨拙,我想知道是否可以只用两三行就完成
(defn drop-last-by [pred coll]
(let [p (partition-by pred coll)]
(apply concat (if (and (seq p) (pred (first (last p))))
(butlast p)
p))))
既然已经基本上满足了您的需求,而且您当前的解决方案已经不是懒惰的,那么我将像这样写最后一个drop by
:
(defn drop-last-by [pred coll]
(reverse (drop-while pred (reverse coll))))
既然已经基本上满足了您的需求,而且您当前的解决方案已经不是懒惰的,那么我将像这样写最后一个drop by
:
(defn drop-last-by [pred coll]
(reverse (drop-while pred (reverse coll))))
以下版本延迟到问题规范允许的程度:
clojure.core/sequence
实现的
(defn drop-last-by
([pred]
(fn [rf]
(let [xs (volatile! [])]
(fn
([] (rf))
([result] (rf result))
([result input]
(if-not (pred input)
(do
(reduce rf result @xs)
(vreset! xs [])
(rf result input))
(do
(vswap! xs conj input)
result)))))))
([pred coll]
(sequence (drop-last-by pred) coll)))
在REPL上:
(drop-last-by odd? [2 1 9 4 7 7 3])
;= (2 1 9 4)
(drop-last-by odd? [2 4])
;= (2 4)
(drop-last-by odd? [9])
;= ()
由其他传感器组成:
(into []
(comp (drop-while even?)
(drop-last-by odd?)
(map #(str "foo " %)))
[0 1 2 3 4 5])
;= ["foo 1" "foo 2" "foo 3" "foo 4"]
以下版本延迟到问题规范允许的程度:
clojure.core/sequence
实现的
(defn drop-last-by
([pred]
(fn [rf]
(let [xs (volatile! [])]
(fn
([] (rf))
([result] (rf result))
([result input]
(if-not (pred input)
(do
(reduce rf result @xs)
(vreset! xs [])
(rf result input))
(do
(vswap! xs conj input)
result)))))))
([pred coll]
(sequence (drop-last-by pred) coll)))
在REPL上:
(drop-last-by odd? [2 1 9 4 7 7 3])
;= (2 1 9 4)
(drop-last-by odd? [2 4])
;= (2 4)
(drop-last-by odd? [9])
;= ()
由其他传感器组成:
(into []
(comp (drop-while even?)
(drop-last-by odd?)
(map #(str "foo " %)))
[0 1 2 3 4 5])
;= ["foo 1" "foo 2" "foo 3" "foo 4"]