Meenakshi
Meenakshi

Reputation: 61

Can we do addition of two or more objects of same type?

I have 3 objects of the same type with different values of their property. I would like to add them together as follow :

For example

objA = { 
    data: {
        SH: { propertyA: 0, propertyB: 3, propertyC: 0},
        ....
    }
}
objB = { 
    data: {
        SH: { propertyA: 0, propertyB: 0, propertyC: 1},
        ....
    }
}
objC = { 
    data: {
        SH: { propertyA: 4, propertyB: 0, propertyC: 0},
        ....
    }
}

And what I want a result like

objC = { 
    data: {
        SH: { propertyA: 4, propertyB: 3, propertyC: 1},
        ...
    } 
}

is it possible to add them?

And if not, do you suggest any efficient way of coding for this instead of having three different types for each of them?

EDIT: By addition, I mean numerical addition of property values from the three objects. Though the objects also have some properties which could be string, I am only interested in number values.

Upvotes: 0

Views: 105

Answers (2)

Bravo
Bravo

Reputation: 6254

As an alternative, here's one that sums any numbers at any level

The non-number values will have the value of the last object processed (this can be changed if required)

This doesn't handle array properties properly

const objA = {
    data: {
        num: 1,
        SH: {
            propertyA: 0,
            propertyB: 3,
            propertyC: 0
        },
        text: 'objA',
        x: {
          y: {
            a: 1,
            b: 2,
            c: 3
          }
        }
    }
};
const objB = {
    data: {
        num: 2,
        SH: {
            propertyA: 0,
            propertyB: 0,
            propertyC: 1
        },
        text: 'objB',
        x: {
          y: {
            b: 4
          }
        }
    }
};
const objC = {
    data: {
        SH: {
            propertyA: 4,
            propertyB: 0,
            propertyC: 0
        },
        text: 'hello world',
        x: {
          y: {
            a: 1
          }
        }
    }
};

const addObjects = (...objs) => objs.reduce((result, obj) => {
        const fn = (obj, dest = result) => {
            Object.entries(obj).forEach(([key, value]) => {
                if (typeof value === 'object') {
                    dest[key] = dest[key] || {};
                    fn(value, dest[key]);
                } else {
                    if (typeof value === 'number') {
                        dest[key] = (dest[key] || 0) + value;
                    } else {
                        dest[key] = value;
                    }
                }
            });
            return result;
        };
        return fn(obj, result);
    }, {}
);
console.log(addObjects(objA, objB, objC));

Upvotes: 2

epascarello
epascarello

Reputation: 207491

In the end it is a lot of looping. How you do the looping can be done a bunch of ways. Easiest way os to look over the objects themselves and add things when they do not exist.

objA = { 
    data: {
        SH: { propertyA: 0, propertyB: 3, propertyC: 0, x: 'funky-chicken'},
        OP: { OO: 1, ZZ: 2 },
    }
}
objB = { 
    data: {
        SH: { propertyA: 0, propertyB: 0, propertyC: 1, x: 'funky-chicken'},
        OP: { OO: 1, YY: 100 },
    }
}
objC = { 
    data: {
        SH: { propertyA: 4, propertyB: 0, propertyC: 0},
        AA: { A: 1 },
    }
}

const result = [objA, objB, objC].reduce(({ data }, obj) => {
  const entries = Object.entries(obj.data);
  entries.forEach(([key, items]) => {
    if (!data[key]){
      data[key] = { ...items };
    } else {
      Object.entries(items).forEach(([item, value]) => {
        if(typeof value === 'number') {
          data[key][item] = ( data[key][item] || 0 ) + value;
        }
      });
    }
  });
  return { data };
}, { data: {} })
console.log(result);

Upvotes: 3

Related Questions