diff --git a/README.md b/README.md index 9478158..d634080 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![npm](http://img.shields.io/npm/v/objectfn.svg?style=flat)](https://badge.fury.io/js/objectfn) [![tests](http://img.shields.io/travis/jescalan/objectfn/master.svg?style=flat)](https://travis-ci.org/jescalan/objectfn) [![dependencies](http://img.shields.io/david/jescalan/objectfn.svg?style=flat)](https://david-dm.org/jescalan/objectfn) [![coverage](http://img.shields.io/coveralls/jescalan/objectfn.svg?style=flat)](https://coveralls.io/github/jescalan/objectfn) -`map`, `reduce`, `forEach`, and `filter` for plain objects. Lazy evaluation, supports functional & imperative syntax, no dependencies. +`map`, `reduce`, `forEach`, and `filter` for plain objects. Lazy evaluation, supports functional and imperative syntax, no dependencies. ### Why should you care? @@ -18,7 +18,9 @@ Also, big props to [@declandewet](https://github.com/declandewet) for the initia Using a terminal: -`npm install objectfn -S` +```sh +$ npm install objectfn -S +``` ### Usage @@ -33,17 +35,21 @@ const {map, reduce, filter, forEach} = require('objectfn') const obj = { foo: 'bar', wow: 'doge' } -map(obj, (val, key) => val.toUpperCase()) +const upcasedValues = map(obj, (val) => val.toUpperCase()) +console.log(upcasedValues) // { foo: 'BAR', wow: 'DOGE' } -reduce(obj, (accum, val, key) => accum[val.toUpperCase()] = key && accum }, {}) +const upcasedKeys = reduce(obj, (acc, val, key) => acc[val.toUpperCase()] = key && acc }, {}) +console.log(upcasedKeys) // { FOO: 'bar', WOW: 'doge' } -filter(obj, (val, key) => !key === 'foo') +const withoutFoo = filter(obj, (val, key) => key !== 'foo') +console.log(withoutFoo) // { wow: 'doge' } forEach(obj, console.log.bind(console)) -// logs out all the values +// bar +// doge ``` #### Functional style @@ -55,36 +61,43 @@ const {map, reduce, filter, forEach} = require('objectfn') const obj = { foo: 'bar', wow: 'doge' } -const mapper = map((val, key) => val.toUpperCase()) -mapper(obj) +const upcaseValues = map((val) => val.toUpperCase()) +console.log(upcaseValues(obj)) // { foo: 'BAR', wow: 'DOGE' } -const reducer = reduce((accum, val, key) => accum[val.toUpperCase()] = key && accum }, {}) -reducer(obj) +const upcaseKeys = reduce((acc, val, key) => acc[val.toUpperCase()] = key && acc }, {}) +console.log(upcaseKeys(obj)) // { FOO: 'bar', WOW: 'doge' } -const filterer = filter((val, key) => !key === 'foo') -filterer(obj) +const ignoreFoo = filter((val, key) => key !== 'foo') +console.log(ignoreFoo(obj)) // { wow: 'doge' } -const iterator = forEach(console.log.bind(console)) -iterator(obj) -// logs out all the values +const logValues = forEach(console.log.bind(console)) +logValues(obj) +// bar +// doge ``` ### Method Signature -Each callback has a method signature of `(value, key, index, object)` with the exception of `reduce`, which has `(accumulator, value, key, index, object)`. `value` is the current key's value, `key` is the current key's name, `index` is the 0-based index of the current key and `object` is the original object. +- Each callback has a method signature of `(value, key, index, object)` with the exception of `reduce`. + - `value` is the current key's value + - `key` is the current key's name + - `index` is the 0-based index of the current key + - `object` is the original object. +- `reduce` has a method signature of `(accumulator, value, key, index, object)`. + - `accumulator` is any initial value onto which you want to iteratively reduce from `object`. ### Differences in `reduce` -Unlike the native array equivalent as well as other library implementations, we felt it would be better to explicitly require the passing of an accumulator to the `reduce` method. +In `objectfn`, the act of passing an accumulator to the `reduce` method is _required_, which is better for readability/accessibility (developer intentions are made more obvious), has no immediate disadvantages and is one of the two reasons `objectfn` is able to support both functional and imperative syntaxes. This means that this will work: ```js let obj = { one: 1, two: 2, three: 3, four: 4 } -reduce(obj, (accum, val) => accum + val, 0) // => 10 +reduce(obj, (acc, val) => acc + val, 0) // => 10 ``` But this will not: @@ -96,7 +109,7 @@ reduce(obj, (prevVal, currVal) => prevVal + currVal) // => wat? ### Binding `this` -Unlike native (and a small handful of other third-party) implementations, this library offers no mechanism for binding the `this` context of the callback via the last parameter. If you want this, it is far more readable to do so using `Function.prototype.bind`: +`objectfn` offers no mechanism for binding the `this` context of the callback via the last parameter. This is one of two reasons why `objectfn` is able to support both functional and imperative syntaxes. If you want this behavior, it is still possible (and far more readable) to do so using `Function.prototype.bind`: ```js map(obj, fn.bind(/* value to use as `this` goes here */))