lodash mergeWith, skip with some key

Viewed 3975
function merger(objValue, srcValue, key, object, source, stack) {
  switch (key) {
    case 'keya':
    case 'keyb':
    case 'keyc':
      return null
  }
}

mergeWith({}, oldObj, newObj, merger)

I would like to skip merging when key is equal to some value. But the output from above code will have the output as {keya: null} when newObj has keya.

Can I skip the merge so that the key is not in the output?

3 Answers

This can totally be done like this:

function customMerge(destination, source, skip) {
    return _.mergeWith(
        destination,
        source,
        (objValue, srcValue, key) => {
            if (srcValue === skip) {
                _.unset(destination, key);
            }
        }
    );
}

Here's an implementation of omitDeep that will omit any key/value that passes the predicate anywhere in the object structure.

function omitDeep(value, predicate = (val) => !val) {
  return _.cloneDeepWith(value, makeOmittingCloneDeepCustomizer(predicate))
}

function makeOmittingCloneDeepCustomizer(predicate) {
  return function omittingCloneDeepCustomizer(value, key, object, stack) {
    if (_.isObject(value)) {
      if (_.isArray(value)) {
        return _(value).reject(predicate).map(item => _.cloneDeepWith(item, omittingCloneDeepCustomizer))
      }

      const clone = {}
      for (const subKey of Object.keys(value)) {
        if (!predicate(value[subKey])) {
          clone[subKey] = _.cloneDeepWith(value[subKey], omittingCloneDeepCustomizer)
        }
      }
      return clone
    }

    return undefined
  }
}
Related