diff --git a/README.md b/README.md index 8e60749..2d7b5ae 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,63 @@ My faithful `(reduce-by kf f init coll)` is now `(into {} (x/by-key kf (x/reduce `(frequencies coll)` is `(into {} (x/by-key identity (x/reduce x/count)) coll)`. +## On key-value pairs + +Clojure `reduce-kv` is able to reduce key value pairs without allocating vectors or map entries: the key and value +are passed as second and third arguments of the reducing function. + +Xforms allows a reducing function to advertise its support for key value pairs (3-arg arity) by implementing the `KvRfable` protocol (in practice using the `kvrf` macro). + +Several xforms transducers and transducing contexts leverage `reduce-kv` and `kvrf`. When used together pairs can be transformed without allocating them. + +
| fn | kvs in? | kvs out? + |
|---|---|---|
| `for` | when first binding is a pair | when `body-expr` is a pair + |
| `reduce` | when is `f` is a kvrf | no + |
| 1-arg `into` (transducer) | when `to` is a map | no + |
| 3-arg `into` (transducing context) | when `from` is a map | when `to` is a map + |
| `by-key` (as a transducer) | when is `kfn` and `vfn` are unspecified or `nil` | when `pair` is `vector` or unspecified + |
| `by-key` (as a transducing context on values) | no | no + |