From 92ae098659f2fc81e33efe428069236d2d94eebb Mon Sep 17 00:00:00 2001 From: Aaron Jensen Date: Sun, 9 Aug 2015 00:21:24 -0700 Subject: [PATCH] Make u.map return same instance if nothing changes --- CHANGELOG.md | 1 + lib/map.js | 34 ++++++++++++++++++++++++++++------ test/map-spec.js | 13 +++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de485c2..4dc8059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change Log ## [unreleased] +* `u.map` will now return the same instance if nothing changes. * Removed a couple lodash dependencies. ## [0.5.0] diff --git a/lib/map.js b/lib/map.js index a7eecfe..ecf016b 100644 --- a/lib/map.js +++ b/lib/map.js @@ -1,15 +1,37 @@ -import mapValues from 'lodash/object/mapValues'; import update from './update'; import wrap from './wrap'; -function map(iteratee, object) { - const updater = update(iteratee); - +function forEach(object, callback) { if (Array.isArray(object)) { - return object.map(updater); + object.forEach(callback); + } else { + Object.keys(object).forEach((key) => callback(object[key], key)); + } +} + +function clone(object) { + if (Array.isArray(object)) { + return [...object]; } - return mapValues(object, updater); + return { ...object }; +} + +function map(iteratee, object) { + const updater = update(iteratee); + let newObject; + + forEach(object, (value, index) => { + const newValue = updater(value, index); + + if (newValue === value) return; + + newObject = newObject || clone(object); + + newObject[index] = newValue; + }); + + return newObject || object; } export default wrap(map); diff --git a/test/map-spec.js b/test/map-spec.js index d20d716..198c00b 100644 --- a/test/map-spec.js +++ b/test/map-spec.js @@ -25,6 +25,19 @@ describe('u.map', () => { expect(result).to.eql([{ a: 1 }, { a: 1 }]); }); + it('returns the same object if no updates are made', () => { + const array = [0, 1]; + const ident = x => x; + let result = u.map(ident, array); + + expect(result).to.equal(array); + + const object = { a: 0 }; + result = u.map(ident, object); + + expect(result).to.equal(object); + }); + it('passes the key or index as the second parameter to the iteratee', () => { const object = { a: { x: 0 },