From 1a1e2b313a3187ca957f532a4345e967d13b97c7 Mon Sep 17 00:00:00 2001 From: Aaron Jensen Date: Wed, 5 Aug 2015 00:25:34 -0700 Subject: [PATCH] Add u.map --- CHANGELOG.md | 1 + README.md | 28 ++++++++++++++++++++++++ lib/index.js | 7 ++++-- lib/map.js | 17 +++++++++++++++ test/map-spec.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 lib/map.js create mode 100644 test/map-spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index a95a4ad..7e5d913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [unreleased] * Add `u.if` to conditionally update objects. +* Add `u.map` to update all values in an array or object. ## [0.3.1] * Actually expose `u.in`. diff --git a/README.md b/README.md index 734c800..9815e35 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,34 @@ u({ // => { a: 3 } ``` +### `u.map(iteratee(, object))` + +If iteratee is a function, map it over the values in `object`. +If it is an object, apply it as updates to each value in `object`, +which is equivalent to `u.map(u(...), obj)`). + +```js +function inc(x) { return x + 1; } +u({ + a: u.map(inc) +}, { a: [0, 1] }); +// => { a: [1, 2] } +``` + +```js +function inc(x) { return x + 1; } +u.map(inc, [0, 1, 2]); +// => [1, 2, 3] + +u.map(inc, { a: 0, b: 1, c: 2}); +// => { a: 1, b: 2, c: 3} +``` + +```js +u.map({ a: 2 }, [{ a: 0 }, { a: 1 }]); +// => [{ a: 2 }, { a: 2 }] +``` + ### `u.omit(predicate(, object))` Remove properties. See [`_.omit`](https://lodash.com/docs#omit). diff --git a/lib/index.js b/lib/index.js index 45da618..1fcbf55 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,10 +1,12 @@ -import update from './update'; +import freeze from './freeze'; import _in from './in'; import _if from './if'; +import map from './map'; import omit from './omit'; import reject from './reject'; import withDefault from './withDefault'; -import freeze from './freeze'; +import update from './update'; + import curry from 'lodash/function/curry'; function updateAndFreeze(updates, obj) { @@ -16,6 +18,7 @@ const updeep = curry(updateAndFreeze); updeep.if = _if; updeep.in = _in; updeep.freeze = freeze; +updeep.map = map; updeep.omit = omit; updeep.reject = reject; updeep.withDefault = withDefault; diff --git a/lib/map.js b/lib/map.js new file mode 100644 index 0000000..9f816e6 --- /dev/null +++ b/lib/map.js @@ -0,0 +1,17 @@ +import curry from 'lodash/function/curry'; +import mapValues from 'lodash/object/mapValues'; +import update from './update'; + +function map(iteratee, object) { + const updater = typeof iteratee === 'function' ? + iteratee : + val => update(iteratee, val); + + if (Array.isArray(object)) { + return object.map(updater); + } + + return mapValues(object, updater); +} + +export default curry(map); diff --git a/test/map-spec.js b/test/map-spec.js new file mode 100644 index 0000000..43d1334 --- /dev/null +++ b/test/map-spec.js @@ -0,0 +1,55 @@ +import { expect } from 'chai'; +import u from '../lib'; + +describe('u.map', () => { + it('applies updates to each item in an array', () => { + const obj = [0, 1, 2]; + const inc = x => x + 1; + const result = u.map(inc, obj); + + expect(result).to.eql([1, 2, 3]); + }); + + it('applies updates to each value in an object', () => { + const obj = { a: 0, b: 1, c: 2 }; + const inc = x => x + 1; + const result = u.map(inc, obj); + + expect(result).to.eql({ a: 1, b: 2, c: 3 }); + }); + + it('can update with a regular updates object', () => { + const obj = [{ a: 0 }, { a: 0 }]; + const result = u.map({ a: 1 }, obj); + + expect(result).to.eql([{ a: 1 }, { a: 1 }]); + }); + + it('passes the key or index as the second parameter to the iteratee', () => { + const obj = { + a: { x: 0 }, + b: [3, 3], + }; + const setToKey = (_, key) => key; + const result = u.map(u.map(setToKey), obj); + + expect(result).to.eql( { + a: { x: 'x' }, + b: [0, 1], + }); + }); + + it('can be partially applied', () => { + const obj = { + b: [3, 3], + }; + const setToKey = (_, key) => key; + const result = u({ + b: u.map(setToKey), + }, obj); + + expect(result).to.eql( { + b: [0, 1], + }); + }); +});