Search code examples
javascriptecmascript-6parametersspread-syntax

Using rest/spread syntax to merge an array of objects into a single object


This bit of code works as intended; however, it's not scalabe for any kind of input:

const input = [{optionA: {a: 1}, optionB: {b: 1}, optionC: {c: 1}];
input.map(({optionA, optionB, optionC}) => {
    return Object.assign({}, optionA, optionB, optionC);
});

Question: How can I refactor my map's args and my Object.assign's args to not use destructuring but rather javascript's spread syntax to ensure an output when input keys are unknown in their name and their length?

How can I satisify these test cases?

    const input2 = [{optionZ: {z: 1}, optionY: {y: 1}, optionX: {x: 1}];
    const input3 = [{optionA: {a: 1}, optionB: {b: 1}, optionC: {c: 1},{optionZ: {z: 1}, optionY: {y: 1}, optionX: {x: 1}];

    input2.map(({optionA, optionB, optionC}) => {
        return Object.assign({}, optionA, optionB, optionC);
    });
    input3.map(({optionA, optionB, optionC}) => {
        return Object.assign({}, optionA, optionB, optionC);
    });

Solution

  • Object spread won't work in this case, since the result would be a new object with the properties, and not a list of the values you want to merge.

    Use Object.values() to get the properties' values, and then merge them with Object.assign():

    const fn = obj => Object.assign({}, ...Object.values(obj));
    
    const input2 = [{"optionZ":{"z":1},"optionY":{"y":1},"optionX":{"x":1}}];
    const input3 = [{"optionA":{"a":1},"optionB":{"b":1},"optionC":{"c":1}},{"optionZ":{"z":1},"optionY":{"y":1},"optionX":{"x":1}}];
    
    console.log(input2.map(fn));
    console.log(input3.map(fn));