I have two objects.
object_1 = [{January:50},{February:20},{April:10}, {May:22}]
object_2 = [{January:40},{March:10},{April:5}]
I want the following result
object_result = [{January:90},{February:20},{March:10},{April:15},{May:22}]
Which means, if same key exists in both objects; add two values. Final object should consists of all the keys of the objects. How can I achieve this in JS? Is there a way to sort same as mentioned? (Sorting is not compulsory)
CodePudding user response:
As the others have stated, your structure is unusual and you're probably making things harder for yourself. But, for the sake of your question, let's say you must keep it this way.
function overlyComplicatedFunction(){
//I renamed these because they're arrays, not objects
let array_1 = [{January:50},{February:20},{April:10},{May:22}]
let array_2 = [{January:40},{March:10},{April:5}]
/*
initialize two empty objects that will become what array_1 & array_2 are normally
structured like
*/
let object_1 = {}, object_2 = {}
/*
These are called "anonymous functions" if you want to look that up & learn more
about them. In these functions, each object inside array_1 is "assigned" to object_1,
and each object inside array_2 is "assigned" to object_2, which is essentially
merging each together. Now we have normal objects to work with!
*/
anon = (array_1).forEach(x => Object.assign(object_1,x))
anon = (array_2).forEach(x => Object.assign(object_2,x))
//uncomment the line below if you want to see how the objects are supposed to look
//console.log(object_1,object_2)
/*
The following function takes any number of objects as an input and reduces them
together, combining like keys where possible
*/
function sum(...objects){
return objects.reduce((a, b) => {
for(let j in b)if(b.hasOwnProperty(j))a[j] = (a[j] || 0) b[j]
return a
}, {})
}
/*
Here we call the sum function defined above, using our two normal objects, and stick
it inside an array so it matches the format you're looking for in the end
*/
let sumArray = [sum(object_1,object_2)]
/*
The following function converts an object with multiple keys into multiple objects
with 1 key each, which will match the format of the original inputs
*/
let object_result = Object.keys(sumArray[0]).map(function (k){
let tempObject = {}
tempObject[k] = sumArray[0][k]
return tempObject
})
//This provides the weird answer you're looking for. Good luck!
console.log(object_result)
}
CodePudding user response:
Direct answer
let object_1 = [{January:50},{February:20},{April:10}, {May:22}]
let object_2 = [{January:40},{March:10},{April:5}]
let obj = [...object_1, ...object_2].reduce((acc, item) => {
const [month, value] = Object.entries(item).at(0);
if (!acc.hasOwnProperty(month)) {
acc[month] = 0;
}
acc[month] = value;
return acc;
}, {});
let object_result = Object.entries(obj).map(([month, value]) => ({ [month]: value })));
// [{"January":90},{"February":20},{"April":15},{"May":22},{"March":10}]
Feedback
StackOverflow is a place where you can learn, not only get the answer, so let me give some feedback.
- As already mentioned in the comments: you have an array of objects, that's why you have to call your variables accordingly [ex:
objects_list
] - when you create variables you should use
let
andconst
(take a moment and check the difference) [ex:const objects_list = [{}, ...]
] - Try to change your code to store monthly stats in an object, that would significantly simplify your life [ex:
const monthlyStats = { Jan: 0, Feb: 0, ... }
] - In JS world we usually use
lowerCamelCase
for variables and object keys.
P.S
Use tools like https://jsfiddle.net/ to share your snippets of code in questions, and show your attempt to solve the issue (not only ask) - that would significantly increase your chances to get an answer.