Erased
Erased

Reputation: 571

Merge object properties without overwritting

I know I should use Object.assign for this case but assign overwrite. I want to merge the common properties.

Here is the context :

I have this object array.

let myObjectArray = [
    { p1 : ["0000"], p2: "test", p3: "mamama" },
    { p1 : ["0100"], p2: "blabla", p3: "blablabla" },
    { p1 : ["0431"], p2: "test", p3: "mamama" }
]

Prop1 and prop3 have the same value of properties p2 and p3, only the p1 of both is different. I want to merge this array when p2 and p3 have the same value. Here is the result I want :

let resultArray = [
        { p1 : ["0000", "0431"], p2: "test", p3: "mamama" },
        { p1 : ["0100"], p2: "blabla", p3: "blablabla" },
    ]

I don't know how to do this : using assign()? or double loop to check common value but I should remove the occurence because of the double loop. Is there a better solution?

Upvotes: 1

Views: 58

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386578

You could use a Map as reference to the common values of the given keys and filter the array for existing objects.

let array = [{ p1: ["0000"], p2: "test", p3: "mamama" }, { p1: ["0100"], p2: "blabla", p3: "blablabla" }, { p1: ["0431"], p2: "test", p3: "mamama" }];

array = array.filter((hash => o => {
    let key = ['p2', 'p3'].map(k => o[k]).join('|');
    if (!hash.has(key)) {
        hash.set(key, o);
        return true;
    }
    hash.get(key).p1.push(...o.p1);
})(new Map));
   
console.log(array);

With new objects as result, without mutating the given array.

let array = [{ p1: ["0000"], p2: "test", p3: "mamama" }, { p1: ["0100"], p2: "blabla", p3: "blablabla" }, { p1: ["0431"], p2: "test", p3: "mamama" }],
    result = array.reduce((hash => (r, o) => {
        let key = ['p2', 'p3'].map(k => o[k]).join('|'),
            p = hash.get(key);
 
        if (!p) {
            p = Object.assign({}, o, { p1: [] });
            hash.set(key, p);
            r.push(p);
        }
        p.p1 = p.p1.concat(o.p1);
        return r;
    })(new Map), []);
   
console.log(result);
console.log(array);

Upvotes: 1

Related Questions