- Notifications
You must be signed in to change notification settings - Fork214
A library for deep (recursive) merging of Javascript objects
License
TehShrike/deepmerge
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Merges the enumerable properties of two or more objects deeply.
UMD bundle is 723B minified+gzipped
constx={foo:{bar:3},array:[{does:'work',too:[1,2,3]}]}consty={foo:{baz:4},quux:5,array:[{does:'work',too:[4,5,6]},{really:'yes'}]}constoutput={foo:{bar:3,baz:4},array:[{does:'work',too:[1,2,3]},{does:'work',too:[4,5,6]},{really:'yes'}],quux:5}merge(x,y)// => output
Withnpm do:
npm install deepmerge
deepmerge can be used directly in the browser without the use of package managers/bundlers as well:UMD version from unpkg.com.
deepmerge exposes a CommonJS entry point:
const merge = require('deepmerge')
The ESM entry point was dropped due to aWebpack bug.
Merge two objectsx
andy
deeply, returning a new merged object with theelements from bothx
andy
.
If an element at the same key is present for bothx
andy
, the value fromy
will appear in the result.
Merging creates a new object, so that neitherx
ory
is modified.
Note: By default, arrays are merged by concatenating them.
Merges any number of objects into a single result object.
constfoobar={foo:{bar:3}}constfoobaz={foo:{baz:4}}constbar={bar:'yay!'}merge.all([foobar,foobaz,bar])// => { foo: { bar: 3, baz: 4 }, bar: 'yay!' }
There are multiple ways to merge two arrays, below are a few examples but you can also create your own custom function.
YourarrayMerge
function will be called with three arguments: atarget
array, thesource
array, and anoptions
object with these properties:
isMergeableObject(value)
cloneUnlessOtherwiseSpecified(value, options)
Overwrites the existing array values completely rather than concatenating them:
constoverwriteMerge=(destinationArray,sourceArray,options)=>sourceArraymerge([1,2,3],[3,2,1],{arrayMerge:overwriteMerge})// => [3, 2, 1]
Combines objects at the same index in the two arrays.
This was the default array merging algorithm pre-version-2.0.0.
constcombineMerge=(target,source,options)=>{constdestination=target.slice()source.forEach((item,index)=>{if(typeofdestination[index]==='undefined'){destination[index]=options.cloneUnlessOtherwiseSpecified(item,options)}elseif(options.isMergeableObject(item)){destination[index]=merge(target[index],item,options)}elseif(target.indexOf(item)===-1){destination.push(item)}})returndestination}merge([{a:true}],[{b:true},'ah yup'],{arrayMerge:combineMerge})// => [{ a: true, b: true }, 'ah yup']
By default, deepmerge clones every property from almost every kind of object.
You may not want this, if your objects are of special types, and you want to copy the whole object instead of just copying its properties.
You can accomplish this by passing in a function for theisMergeableObject
option.
If you only want to clone properties of plain objects, and ignore all "special" kinds of instantiated objects, you probably want to drop inis-plain-object
.
const{ isPlainObject}=require('is-plain-object')functionSuperSpecial(){this.special='oh yeah man totally'}constinstantiatedSpecialObject=newSuperSpecial()consttarget={someProperty:{cool:'oh for sure'}}constsource={someProperty:instantiatedSpecialObject}constdefaultOutput=merge(target,source)defaultOutput.someProperty.cool// => 'oh for sure'defaultOutput.someProperty.special// => 'oh yeah man totally'defaultOutput.somePropertyinstanceofSuperSpecial// => falseconstcustomMergeOutput=merge(target,source,{isMergeableObject:isPlainObject})customMergeOutput.someProperty.cool// => undefinedcustomMergeOutput.someProperty.special// => 'oh yeah man totally'customMergeOutput.somePropertyinstanceofSuperSpecial// => true
Specifies a function which can be used to override the default merge behavior for a property, based on the property name.
ThecustomMerge
function will be passed the key for each property, and should return the function which should be used to merge the values for that property.
It may also return undefined, in which case the default merge behaviour will be used.
constalex={name:{first:'Alex',last:'Alexson'},pets:['Cat','Parrot']}consttony={name:{first:'Tony',last:'Tonison'},pets:['Dog']}constmergeNames=(nameA,nameB)=>`${nameA.first} and${nameB.first}`constoptions={customMerge:(key)=>{if(key==='name'){returnmergeNames}}}constresult=merge(alex,tony,options)result.name// => 'Alex and Tony'result.pets// => ['Cat', 'Parrot', 'Dog']
Deprecated.
Defaults totrue
.
Ifclone
isfalse
then child objects will be copied directly instead of being cloned. This was the default behavior before version 2.x.
Withnpm do:
npmtest
MIT
About
A library for deep (recursive) merging of Javascript objects