Skip to content
This repository has been archived by the owner on Jan 6, 2025. It is now read-only.

Commit

Permalink
✨ Add lodash object functions (#83)
Browse files Browse the repository at this point in the history
* ✨ Add object.defaults
* ✨ Add object.mapKeys
* ✨ Add object.merge
* ✨ Add object.omit
* ✨ Add object.omitBy
* ✨ Add object.pick
  • Loading branch information
nlepage authored Sep 3, 2017
1 parent bfa9cba commit 95304da
Show file tree
Hide file tree
Showing 17 changed files with 307 additions and 14 deletions.
5 changes: 2 additions & 3 deletions src/object/assign.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import _assign from 'lodash/assign'
import { convert } from 'util/convert'

/**
* Assigns own enumerable string keyed properties of source objects to the
* destination object. Source objects are applied from left to right.
* Subsequent sources overwrite property assignments of previous sources.
* Replaces by an object assigning own enumerable string keyed properties of source objects to the destination object.<br />
* Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
* @function
* @memberof object
* @param {Object} object The object to modify.
Expand Down
18 changes: 18 additions & 0 deletions src/object/defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import _defaults from 'lodash/defaults'
import { convert } from 'util/convert'

/**
* Replaces by an object assigning own and inherited enumerable string keyed properties of source objects to the destination object for all destination properties that resolve to <code>undefined</code>.<br >
* Source objects are applied from left to right. Once a property is set, additional values of the same property are ignored.
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {...Object} [sources] The source objects.
* @return {Object} Returns the updated object.
* @example defaults({ nested: { a: 1, b: 2 } }, 'nested', { b: 3, c: 4 }) // => { nested: { a:1, b: 2, c: 4 } }
* @see {@link https://lodash.com/docs#defaults|lodash.defaults} for more information.
* @since 0.3.0
*/
const defaults = convert(_defaults)
export { defaults, defaults as default }
34 changes: 34 additions & 0 deletions src/object/defaults.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* eslint-env jest */
import { defaults } from './defaults'
import { immutaTest } from 'test.utils'

describe('Defaults', () => {

it('should assign default properties objects', () => {
immutaTest((input, path) => {
const output = defaults(input, path, {
b: 3,
c: 4,
})
expect(output).toEqual({
nested: {
prop: {
a: 1,
b: 2,
c: 4,
},
},
other: {},
})
return output
}, {
nested: {
prop: {
a: 1,
b: 2,
},
},
other: {},
}, 'nested.prop')
})
})
14 changes: 13 additions & 1 deletion src/object/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import { assign } from './assign'
import { defaults } from './defaults'
import { mapKeys } from './mapKeys'
import { mapValues } from './mapValues'
import { merge } from './merge'
import { omit } from './omit'
import { omitBy } from './omitBy'
import { pick } from './pick'
import { pickBy } from './pickBy'
import { set } from './set'
import { unset } from './unset'
import { update } from './update'

/**
* Array functions.
* Object functions.
* @namespace object
* @since 0.1.12
*/
export {
assign,
defaults,
mapKeys,
mapValues,
merge,
omit,
omitBy,
pick,
pickBy,
set,
unset,
Expand Down
18 changes: 18 additions & 0 deletions src/object/mapKeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import _mapKeys from 'lodash/mapKeys'
import { convert } from 'util/convert'

/**
* Replaces by an object with the same values as the former object and values generated by running each own enumerable string keyed property of the former object thru <code>iteratee</code>.
* The iteratee is invoked with three arguments: (value, key, object).
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {function} [iteratee={@link https://lodash.com/docs#identity|lodash.identity}] The function invoked per iteration.
* @return {Object} Returns the updated object.
* @example mapKeys({ nested: { a: 1, b: 2, c: 3 } }, 'nested', (v, k) => '_' + k) // => { nested: { _a: 1, _b: 2, _c: 3 } }
* @see {@link https://lodash.com/docs#mapKeys|lodash.mapKeys} for more information.
* @since 0.3.0
*/
const mapKeys = convert(_mapKeys)
export { mapKeys, mapKeys as default }
31 changes: 31 additions & 0 deletions src/object/mapKeys.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-env jest */
import { immutaTest } from 'test.utils'
import { mapKeys } from './mapKeys'

describe('MapKeys', () => {
it('should replace the keys of object', () => {
immutaTest((input, path) => {
const output = mapKeys(input, path, (_, k) => `_${k}`)
expect(output).toEqual({
nested: {
prop: {
_a: 1,
_b: 2,
_c: 3,
},
},
other: {},
})
return output
}, {
nested: {
prop: {
a: 1,
b: 2,
c: 3,
},
},
other: {},
}, 'nested.prop')
})
})
9 changes: 3 additions & 6 deletions src/object/mapValues.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ import _mapValues from 'lodash/mapValues'
import { convert } from 'util/convert'

/**
* Creates an object with the same keys as object and values generated by
* running each own enumerable string keyed property of object thru iteratee.
* Replaces by an object with the same keys as the former object and values generated by running each own enumerable string keyed property of object thru <code>iteratee</code>.
* The iteratee is invoked with three arguments: (value, key, object).
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {function} [iteratee={@link https://lodash.com/docs#identity|lodash.identity}] The function invoked per iteration.
* @return {Object} Returns the updated object.
* @example mapValues({ nested: { a: 1, b: 2, c: 3 } }, 'nested', v => v * v) // => { nested: { a:1, b: 4, c: 9 } }
* @example mapValues({ nested: { a: { age: 40, name: 'John' }, b: { age: 30, name: 'Alice' } } }, 'nested', 'age')
* // => { nested: { a: 40, b: 30 } }
* @example mapValues({ nested: { a: 1, b: 2, c: 3 } }, 'nested', v => v * v) // => { nested: { a: 1, b: 4, c: 9 } }
* @example mapValues({ nested: { a: { age: 40, name: 'John' }, b: { age: 30, name: 'Alice' } } }, 'nested', 'age') // => { nested: { a: 40, b: 30 } }
* @see {@link https://lodash.com/docs#mapValues|lodash.mapValues} for more information.
* @see {@link https://lodash.com/docs#identity|lodash.identity} for more information.
* @since 0.1.12
*/
const mapValues = convert(_mapValues)
Expand Down
18 changes: 18 additions & 0 deletions src/object/merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import _merge from 'lodash/fp/merge'
import { convertLodashFp } from 'util/convert'

/**
* Replaces by an object deeply merging own enumerable string keyed properties of source objects to the former object.<br />
* Source objects are applied from left to right. Subsequent sources overwrite properties of previous sources.
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {...Object} [sources] The source objects.
* @return {Object} Returns the updated object.
* @example merge({ nested: { prop: { a: 1 } } }, 'nested', { prop: { a: 2, b: 3 } }) // => { nested: { prop: { a: 2, b: 3 } } }
* @see {@link https://lodash.com/docs#merge|lodash.merge} for more information.
* @since 0.3.0
*/
const merge = convertLodashFp(_merge)
export { merge, merge as default }
30 changes: 30 additions & 0 deletions src/object/merge.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-env jest */
import { immutaTest } from 'test.utils'
import { merge } from './merge'

describe('Merge', () => {

it('should merge objects', () => {
immutaTest((input, path) => {
const output = merge(input, path, {
prop: {
a: 2,
b: 3,
},
})
expect(output).toEqual({
nested: {
prop: {
a: 2,
b: 3,
},
},
other: {},
})
return output
}, {
nested: { prop: { a: 1 } },
other: {},
}, 'nested')
})
})
17 changes: 17 additions & 0 deletions src/object/omit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import _omit from 'lodash/omit'
import { convert } from 'util/convert'

/**
* Replaces by an object omitting specified properties.
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {...(string|string[])} [paths] The property paths to omit.
* @return {Object} Returns the updated object.
* @example omit({ nested: { a: 1, b: 2, c: 3 } }, 'nested', 'b') // => { nested: { a:1, c: 3 } }
* @see {@link https://lodash.com/docs#omit|lodash.omit} for more information.
* @since 0.3.0
*/
const omit = convert(_omit)
export { omit, omit as default }
31 changes: 31 additions & 0 deletions src/object/omit.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-env jest */
import { immutaTest } from 'test.utils'
import { omit } from './omit'

describe('Omit', () => {

it('should omit properties of object', () => {
immutaTest((input, path) => {
const output = omit(input, path, 'b')
expect(output).toEqual({
nested: {
prop: {
a: 1,
c: 3,
},
},
other: {},
})
return output
}, {
nested: {
prop: {
a: 1,
b: 2,
c: 3,
},
},
other: {},
}, 'nested.prop')
})
})
17 changes: 17 additions & 0 deletions src/object/omitBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import _omitBy from 'lodash/omitBy'
import { convert } from 'util/convert'

/**
* Replaces by an object omitting properties that <code>predicate</code> doesn't return truthy for.
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {function} [predicate={@link https://lodash.com/docs#identity|lodash.identity}] The function invoked per property.
* @return {Object} Returns the updated object.
* @example omitBy({ nested: { a: 1, b: 2, c: 3 } }, 'nested', v => v === 2) // => { nested: { a:1, c: 3 } }
* @see {@link https://lodash.com/docs#omitBy|lodash.omitBy} for more information.
* @since 0.3.0
*/
const omitBy = convert(_omitBy)
export { omitBy, omitBy as default }
31 changes: 31 additions & 0 deletions src/object/omitBy.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-env jest */
import { immutaTest } from 'test.utils'
import { omitBy } from './omitBy'

describe('OmitBy', () => {

it('should omit properties matching predicate', () => {
immutaTest((input, path) => {
const output = omitBy(input, path, v => v === 2)
expect(output).toEqual({
nested: {
prop: {
a: 1,
c: 3,
},
},
other: {},
})
return output
}, {
nested: {
prop: {
a: 1,
b: 2,
c: 3,
},
},
other: {},
}, 'nested.prop')
})
})
17 changes: 17 additions & 0 deletions src/object/pick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import _pick from 'lodash/pick'
import { convert } from 'util/convert'

/**
* Replaces by an object picking specified properties.
* @function
* @memberof object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {...(string|string[])} [paths] The property paths to pick.
* @return {Object} Returns the updated object.
* @example pick({ nested: { a: 1, b: 2, c: 3 } }, 'nested', 'b') // => { nested: { b: 2 } }
* @see {@link https://lodash.com/docs#pick|lodash.pick} for more information.
* @since 0.3.0
*/
const pick = convert(_pick)
export { pick, pick as default }
26 changes: 26 additions & 0 deletions src/object/pick.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-env jest */
import { immutaTest } from 'test.utils'
import { pick } from './pick'

describe('Pick', () => {

it('should pick properties of object', () => {
immutaTest((input, path) => {
const output = pick(input, path, 'b')
expect(output).toEqual({
nested: { prop: { b: 2 } },
other: {},
})
return output
}, {
nested: {
prop: {
a: 1,
b: 2,
c: 3,
},
},
other: {},
}, 'nested.prop')
})
})
4 changes: 1 addition & 3 deletions src/object/pickBy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import _pickBy from 'lodash/pickBy'
import { convert } from 'util/convert'

/**
* Creates an object composed of the object properties predicate returns truthy
* for. The predicate is invoked with two arguments: (value, key).
* Replaces by an object picking properties that <code>predicate</code> returns truthy for.
* @function
* @memberof object
* @param {Object} object The object to modify.
Expand All @@ -12,7 +11,6 @@ import { convert } from 'util/convert'
* @return {Object} Returns the updated object.
* @example pickBy({ nested: { a: 1, b: 2, c: 3, d: 4 } }, 'nested', v => v < 3) // => { nested: { a: 1, b: 2 } }
* @see {@link https://lodash.com/docs#pickBy|lodash.pickBy} for more information.
* @see {@link https://lodash.com/docs#identity|lodash.identity} for more information.
* @since 0.1.12
*/
const pickBy = convert(_pickBy)
Expand Down
1 change: 0 additions & 1 deletion src/util/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export { convert, convert as default }
* @return {function} Returns the wrapped function.
* @see {@link util.convert|convert} for more information.
* @since 0.2.0
* @deprecated Unused since 0.3.0 and {@link fix #72|https://github.com/Zenika/immutadot/issues/72}, to be removed ?
* @private
*/
export const convertLodashFp = fn => convert(lodashFpConvert(fn))

0 comments on commit 95304da

Please sign in to comment.