TehShrike / deepmerge

A library for deep (recursive) merging of Javascript objects
MIT License
2.75k stars 216 forks source link

How to merge array items only if they are in the target? #153

Closed halloleo closed 5 years ago

halloleo commented 5 years ago

I want to modify the combineMerge from the ReadMe so that array items only get merged if the inde exists in the target. Example:

x = {
    array: [{
        arrprop_x: 'base_1',
        arrprop_y: 'base_1'
    }, {
        arrprop_x: 'base_2',
        arrprop_y: 'base_2'
    }],
}

y ={
    array: [{
        arrprop_y: 'special',
        arrprop_z: 'special'
    }}
}

Wanted result from deepmerge(x,y, { arrayMerge: combineMerge }):

{
    "array": [
        {
            "arrprop_x": "base_1",
            "arrprop_y": "special",
            "arrprop_z": "special"
        }]
}

(Because only index 0 exists in the target!)

I cannot get my modified combineMerge working for this: I tried to skip the deepmerge in the if (options.isMergeableObject(item)) if-branch, but the items from the source are already copied!

How can I do this?

TehShrike commented 5 years ago

The solution is to write an arrayMerge function that does what you want it to.

From your description it sounds like you want to change the first line in combineMerge from const destination = target.slice() to const destination = target.slice(0, source.length)

But I would suggest that you start by writing unit tests that assert the behavior that you want.

halloleo commented 5 years ago

It works, it works! const destination = target.slice(0, source.length) does the trick. You know your stuff! :-)

The thing I don't understand is why should I limited the destination by the source (via source.length), I thought I want to limit the destination by the target - or are source and target swapped around? If so, why?

Anyway super thanks for your pointer! :-)

TehShrike commented 5 years ago

You said

array items only get merged if the inde exists in the target

which sounds like "items in the source don't get merged if their index doesn't exist in the target array" :-x

halloleo commented 5 years ago

Actually I realised that source and target are in deed swapped to what I had assumed... Makes all sense now.

BTW, it is really cool to have arrayMerge and customMerge hooks: Together they allow for a lot of customisation!