0.13.0 x/without, the opposite of x/into: dissoc/disj'ing instead of conj'ing.

This commit is contained in:
Christophe Grand 2017-10-26 18:09:32 +02:00
parent 37d4732117
commit 0515b711df
4 changed files with 44 additions and 4 deletions

View file

@ -12,7 +12,7 @@ In `net.cgrand.xforms`:
* regular ones: `partition` (1 arg), `reductions`, `for`, `take-last`, `drop-last`, `window` and `window-by-time`
* higher-order ones: `by-key`, `into-by-key`, `multiplex`, `transjuxt`, `partition` (2+ args)
* 1-item ones: `reduce`, `into`, `transjuxt`, `last`, `count`, `avg`, `sd`, `min`, `minimum`, `max`, `maximum`, `str`
* 1-item ones: `reduce`, `into`, `without`, `transjuxt`, `last`, `count`, `avg`, `sd`, `min`, `minimum`, `max`, `maximum`, `str`
In `net.cgrand.xforms.io`:
* `sh` to use any process as a transducer
@ -27,7 +27,7 @@ In `net.cgrand.xforms.io`:
*Transducing contexts*:
* in `net.cgrand.xforms`: `transjuxt` (for performing several transductions in a single pass), `iterator` (clojure only), `into`, `count` and `some`.
* in `net.cgrand.xforms`: `transjuxt` (for performing several transductions in a single pass), `iterator` (clojure only), `into`, `without`, `count` and `some`.
* in `net.cgrand.xforms.io`: `line-out` (3+ args) and `edn-out` (3+ args).
*Reducible views* (in `net.cgrand.xforms.io`): `lines-in` and `edn-in`.
@ -37,7 +37,7 @@ In `net.cgrand.xforms.io`:
Add this dependency to your project:
```clj
[net.cgrand/xforms "0.12.1"]
[net.cgrand/xforms "0.13.0"]
```
```clj

View file

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

View file

@ -196,6 +196,42 @@
(rf (core/reduce-kv rf (rf) from))
(rf (core/reduce rf (rf) from))))))
(defn- without-rf [from]
(cond
#?(:clj (instance? clojure.lang.IEditableCollection from)
:cljs (satisfies? IEditableCollection from))
(if (map? from)
(fn
([] (transient from))
([acc] (persistent! acc))
([acc x] (dissoc! acc x)))
(fn
([] (transient from))
([acc] (persistent! acc))
([acc x] (disj! acc x))))
(map? from)
(fn
([] from)
([acc] acc)
([acc x] (dissoc acc x)))
:else
(fn
([] from)
([acc] acc)
([acc x] (disj acc x)))))
(defn without
"The opposite of x/into: dissociate or disjoin from the target."
([target]
(reduce (without-rf target)))
([target keys]
(without target identity keys))
([target xform keys]
(let [rf (xform (without-rf target))]
(if-let [rf (and (map? keys) (kvreducible? keys) (some-kvrf rf))]
(rf (core/reduce-kv rf (rf) keys))
(rf (core/reduce rf (rf) keys))))))
(defn minimum
([comparator]
(minimum comparator nil))

View file

@ -90,6 +90,10 @@
(is (= (into [] (comp (x/partition 2 2 nil) (x/into [])) (range 8))
[[[0 1] [2 3] [4 5] [6 7]]])))
(deftest without
(is (= {0 :ok 2 :ok 4 :ok 6 :ok 8 :ok} (x/without (zipmap (range 10) (repeat :ok)) (filter odd?) (range 20))))
(is (= #{0 2 4 6 8 } (x/without (set (range 10)) (filter odd?) (range 20)))))
#?(:clj
(deftest iterator
(is (true? (.hasNext (x/iterator x/count (.iterator (range 5))))))