Created
October 20, 2019 19:47
-
-
Save rjhilgefort/261bb26bfc6d3a5074dc0bbeeea4e3fc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { isArray, curry, isPlainObject, isFunction, isNil } from 'lodash/fp' | |
import { mapValuesWithKey } from './mapValuesWithKey' | |
import { mapWithKey } from './mapWithKey' | |
const iteratee = (spec, full) => (val, key) => fn(spec[key], val, full) | |
const fn = (spec, data, full) => { | |
if (isNil(spec)) return data | |
if (isFunction(spec)) return spec(full) | |
if (isPlainObject(spec)) return mapValuesWithKey(iteratee(spec, full), data) | |
if (isArray(spec)) return mapWithKey(iteratee(spec, full), data) | |
return data | |
} | |
/** | |
* @name evolveSpec | |
* | |
* @description | |
* Like `evolve`, but useful when you need to modify a prop on an object/array, | |
* but need the entire object/array context (instead of just the prop value). | |
* | |
* @see ramda.evolve | |
* | |
* @example | |
* evolveSpec( | |
* { name: ({ _key, name }) => `${name} (${_key})` }, | |
* { _key: 'k_1', name: 'Some name' }, | |
* ) // -> { _key: 'k_1', name: 'Some name (k_1)' } | |
* | |
* @signature | |
* { [String]: a -> Any } -> Object a -> Object b | |
*/ | |
export const evolveSpec = curry((spec, data) => fn(spec, data, data)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { evolveSpec } from './' | |
it.each([ | |
['`null` spec', null, { foo: 'foo' }, { foo: 'foo' }], | |
[ | |
'simple object', | |
{ name: ({ _key, name }) => `${name} (${_key})` }, | |
{ _key: 'k_1', name: 'Some name' }, | |
{ _key: 'k_1', name: 'Some name (k_1)' }, | |
], | |
[ | |
'nested object', | |
{ foo: { name: ({ foo: { _key, name } }) => `${name} (${_key})` } }, | |
{ foo: { _key: 'k_1', name: 'Some name' }, bar: 5 }, | |
{ foo: { _key: 'k_1', name: 'Some name (k_1)' }, bar: 5 }, | |
], | |
[ | |
'simple array', | |
[null, ([_key, name]) => `${name} (${_key})`], | |
['k_1', 'Some name'], | |
['k_1', 'Some name (k_1)'], | |
], | |
[ | |
// Probably don't do this, but it's supported | |
'nested array', | |
[null, [null, ([, [_key, name]]) => `${name} (${_key})`]], | |
[5, ['k_1', 'Some name'], 6], | |
[5, ['k_1', 'Some name (k_1)'], 6], | |
], | |
])('%p', (_label, spec, data, expected) => { | |
expect(evolveSpec(spec, data)).toEqual(expected) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment