objectfn
v2.0.0
Published
map, reduce, and filter for objects, lazy evaluation and no dependencies
Downloads
75
Readme
ObjectFn
map
, reduce
, forEach
, and filter
for plain objects. Lazy evaluation, supports functional and imperative syntax, no dependencies.
Why should you care?
I wanted a library that has no dependencies and gives me the basic map/reduce/filter for use on objects. Any existing library I found has boatloads of dependencies, provides tons more extra tools, and/or is unmaintained. So here's ObjectFn
, just for you!
Also, big props to @declandewet for the initial implementation of this library!
Requirements
Installation
Using a terminal:
$ npm install objectfn -S
Usage
Usage is straightforward. Just import what you need and use it on an object.
Imperative style
Takes data first, callback last.
const {map, reduce, filter, forEach} = require('objectfn')
const obj = { foo: 'bar', wow: 'doge' }
map(obj, (val) => val.toUpperCase())
// { foo: 'BAR', wow: 'DOGE' }
reduce(obj, (acc, val, key) => (acc[key.toUpperCase()] = val, acc), {})
// { FOO: 'bar', WOW: 'doge' }
filter(obj, (val, key) => key !== 'foo')
// { wow: 'doge' }
forEach(obj, console.log.bind(console))
// bar foo 0 { foo: 'bar', wow: 'doge' }
// doge wow 1 { foo: 'bar', wow: 'doge' }
Functional style
Takes callback first, data last. Each method is automatically curried.
const {map, reduce, filter, forEach} = require('objectfn')
const obj = { foo: 'bar', wow: 'doge' }
const upcaseValues = map((val) => val.toUpperCase())
upcaseValues(obj)
// { foo: 'BAR', wow: 'DOGE' }
const upcaseKeys = reduce((acc, val, key) => (acc[key.toUpperCase()] = key, acc), {})
upcaseKeys(obj)
// { FOO: 'bar', WOW: 'doge' }
const ignoreFoo = filter((val, key) => key !== 'foo')
ignoreFoo(obj)
// { wow: 'doge' }
const logValues = forEach(console.log.bind(console))
logValues(obj)
// bar foo 0 { foo: 'bar', wow: 'doge' }
// doge wow 1 { foo: 'bar', wow: 'doge' }
Method Signature
- Each callback has a method signature of
(value, key, index, object)
with the exception ofreduce
.value
is the current key's valuekey
is the current key's nameindex
is the 0-based index of the current keyobject
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 fromobject
.
Differences in reduce
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:
let obj = { one: 1, two: 2, three: 3, four: 4 }
reduce(obj, (acc, val) => acc + val, 0) // => 10
But this will not:
let obj = { one: 1, two: 2, three: 3, four: 4 }
reduce(obj, (prevVal, currVal) => prevVal + currVal) // => wat?
Binding this
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
:
map(obj, fn.bind(/* value to use as `this` goes here */))
License & Contributing
- Details on the license can be found here
- Details on running tests and contributing can be found here