1

What is the best way to subtract or add values ​​from identical objects?

const obj1 = {
  1: 10,
  2: 10,
  3: 10,
  4: 10,
};

const obj2 = {
  1: 30,
  2: 30,
  3: 30,
  4: 30,
};

const result = obj2 - obj1;

console.log(result);

/* the expected output is: 
{
    1:20,
    2: 20,
    3: 20,
    4: 20,
};
*/

ESLint points out that using for in to add values ​​is not a good practice and the log is "guard-for-in: The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype. "

for (const p in obj2) {
  newObj[p] = obj2[p] - obj1[p];
}
console.log(newObj);

Doing with for in I also had problems returning unwanted values ​​like $init":0 when using an array of objects.

Unmitigated
  • 76,500
  • 11
  • 62
  • 80

3 Answers3

3

You can reduce over Object.keys, which provides the object's own property names and will not find keys from the prototype chain.

const obj1 = {
  1: 10,
  2: 10,
  3: 10,
  4: 10,
};

const obj2 = {
  1: 30,
  2: 30,
  3: 30,
  4: 30,
};
const obj3 = Object.keys(obj2)
    .reduce((acc,curr)=>(acc[curr]=obj2[curr]-obj1[curr],acc),{});
console.log(obj3);

ESLint is pointing out the fact that you are not using Object#hasOwnProperty to make sure you are only looping over keys of the object itself and not inherited ones.

for (const p in obj2) {
  if(obj2.hasOwnProperty(p))
       newObj[p] = obj2[p] - obj1[p];
}
console.log(newObj);
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • ... and if ESLint is complaning about `obj2.hasOwnProperty()` because of a [`no-prototype-builtins`](https://eslint.org/docs/rules/no-prototype-builtins) rule, you can do `Object.prototype.hasOwnProperty.call(obj2, p)` – blex Jul 08 '20 at 19:39
3

ESLint's warning means that with in you will also iterate properties on the object's prototype chain, not only the properties owned by the object.

You could use Object.entries which only visits owned properties, and Object.fromEntries to build the result:

const obj1 = { 1: 10, 2: 10, 3: 10, 4: 10 };
const obj2 = { 1: 30, 2: 30, 3: 30, 4: 30 };
const obj3 = Object.fromEntries(
    Object.entries(obj2).map( ([k, v]) => [k, v - obj1[k]] )
);
console.log(obj3);
trincot
  • 317,000
  • 35
  • 244
  • 286
1

const obj1 = {
  1: 10,
  2: 10,
  3: 10,
  4: 10,
};

const obj2 = {
  1: 30,
  2: 30,
  3: 30,
  4: 30,
};

const diff = (obj1, obj2) => {
  const result = Object.assign({}, obj1);
  Object.keys(result).forEach((key) => {
    result[key] -= obj2[key];
  });
  return result;
}

const result = diff(obj2, obj1);

console.log(result);
Sergio Belevskij
  • 2,478
  • 25
  • 24