v0.9.0 add take-last and drop-last

This commit is contained in:
Christophe Grand 2017-02-02 13:16:51 +01:00
parent 8a9d383198
commit 64eb4c6158
3 changed files with 35 additions and 6 deletions

View file

@ -8,7 +8,7 @@ More transducers and reducing functions for Clojure(script)!
(which accept other transducers as arguments) and 1-item ones which emit only 1 item out no matter how many went in.
They generally only make sense in the context of a higher-order transducer.
* regular ones: `partition` (1 arg), `reductions`, `for`, `window` and `window-by-time`
* regular ones: `partition` (1 arg), `reductions`, `for`, `take-last`, `drop-last`, `window` and `window-by-time`
* higher-order ones: `by-key`, `multiplex`, `transjuxt`, `partition` (2+ args)
* 1-item ones: `reduce`, `into`, `transjuxt`, `last`, `count`, `avg`, `sd`, `min`, `minimum`, `max`, `maximum`, `str`
@ -21,7 +21,7 @@ Transducing contexts: `transjuxt` (for performing several transductions in a sin
Add this dependency to your project:
```clj
[net.cgrand/xforms "0.8.3"]
[net.cgrand/xforms "0.9.0"]
```
```clj

View file

@ -1,4 +1,4 @@
(defproject net.cgrand/xforms "0.8.3"
(defproject net.cgrand/xforms "0.9.0"
:description "Extra transducers for Clojure"
:url "https://github.com/cgrand/xforms"
:license {:name "Eclipse Public License"

View file

@ -5,7 +5,7 @@
[net.cgrand.macrovich :as macros]
[net.cgrand.xforms :refer [for kvrf let-complete]])
:clj (:require [net.cgrand.macrovich :as macros]))
(:refer-clojure :exclude [reduce reductions into count for partition str last keys vals min max])
(:refer-clojure :exclude [reduce reductions into count for partition str last keys vals min max drop-last take-last])
(:require [#?(:clj clojure.core :cljs cljs.core) :as core]
[net.cgrand.xforms.rfs :as rf])
#?(:cljs (:import [goog.structs Queue])))
@ -276,7 +276,8 @@
(macros/replace
[#?(:cljs {(java.util.ArrayDeque. n) (Queue.)
.add .enqueue
.poll .dequeue})
.poll .dequeue
.size .getCount})
#?(:clj {(.getValues dq) dq})]
(defn partition
@ -334,7 +335,35 @@
(dotimes [_ (core/min n step)] (.poll dq))
(vswap! barrier + step)
acc)
acc)))))))))
acc))))))))
(defn take-last [n]
(fn [rf]
(let [dq (java.util.ArrayDeque. n)]
(fn
([] (rf))
([acc] (transduce (map #(if (identical? dq %) nil %)) rf acc (.getValues dq)))
([acc x]
(.add dq (if (nil? x) dq x))
(when (< n (.size dq)) (.poll dq))
acc)))))
(defn drop-last
([] (drop-last 1))
([n]
(fn [rf]
(let [dq (java.util.ArrayDeque. n)
xform (map #(if (identical? dq %) nil %))
rf (xform rf)]
(fn
([] (rf))
([acc] (rf acc))
([acc x]
(.add dq (if (nil? x) dq x))
(if (< n (.size dq))
(rf acc (.poll dq))
acc)))))))
)
(defn reductions
"Transducer version of reductions. There's a difference in behavior when init is not provided: (f) is used.