I have two objects like that:
const object1 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]}
const object2 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]}
(object1
and object2
could have array of lenght > 1, for example:
const object1 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]}
const object2 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}, {timestamp: "2018-12-09T16:30:00.000", count: 0}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]}
)
and I want an object of the same format but:
timestamp
should be a real data not a string (so I need to do new Data(timestamp)
)count
should be the sumSo the expected result is:
const res = {first: [{timestamp: 2018-12-09T16:00:00.000, count: 3}], second: [{timestamp: 2018-12-09T17:00:00.000, count: 2}], third: [{timestamp: 2018-12-09T18:00:00.000, count: 5}]}
( if object1
and object2
have array of length > 1:
const res = {first: [{timestamp: 2018-12-09T16:00:00.000, count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}], second: [{timestamp: 2018-12-09T17:00:00.000, count: 2}], third: [{timestamp: 2018-12-09T18:00:00.000, count: 5}]}
)
I used mergeWith
of Lodash in this way:
const merged = _.mergeWith(object1, object2, (objValue, srcValue) => [
{ count: objValue[0].count + srcValue[0].count },
])
const r = Object.entries(merged).map(([key, value], i) => {
return { number: key, timestamp: value.map(convertTimestamp) }
})
console.log('r: ', r)
where convertTimestamp
is:
const convertTimestamp = (d) => ({
...d,
timestamp: new Date(d.timestamp),
})
This is the result:
[
{
"number": "first",
"timestamp": [
{
"count": 3,
"timestamp": null
}
]
},
{
"number": "second",
"timestamp": [
{
"count": 2,
"timestamp": null
}
]
},
{
"number": "third",
"timestamp": [
{
"count": 5,
"timestamp": null
}
]
}
]
Obviously it doesnt' work. It has 3 problems:
object1
and object2
have the same key but If they are:const object1 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]}
const object2 = {second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]}
(object2 is missing first
), that procedure doesn't work...
I need help
Here a testable code:
function mergeData(object1, object2) {
const merged = _.mergeWith(object1, object2, (objValue, srcValue) => [
{ count: objValue[0].count + srcValue[0].count},
])
const r = Object.entries(merged).map(([key, value], i) => {
return { number: key, timestamp: value.map(convertTimestamp) }
})
return r
}
const convertTimestamp = (d) => {
return ({
...d,
timestamp: new Date(d.timestamp),
})
}
const object1 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]}
const object2 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]}
const result = mergeData(object1, object2)
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Some examples:
// example 1
const object1 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]
}
const object2 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}, {timestamp: "2018-12-09T16:30:00.000", count: 0}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]
}
const result = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 5}]
}
// example 2
const object1 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]
}
const object2 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]
}
const result = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 5}]
}
// example 3
const object1 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]
}
const object2 = {
second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]
}
const result = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 5}]
}
// example 4
const object1 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}, {timestamp: "2018-12-09T17:30:00.000", count: 20}, {timestamp: "2018-12-09T18:00:00.000", count: 10}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]
}
const object2 = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}, {timestamp: "2018-12-09T16:30:00.000", count: 0}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}, {timestamp: "2018-12-09T17:30:00.000", count: 6}, {timestamp: "2018-12-09T18:00:00.000", count: 2}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]
}
const result = {
first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}, {timestamp: "2018-12-09T16:30:00.000", count: 5}],
second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}, {timestamp: "2018-12-09T17:30:00.000", count: 26}, {timestamp: "2018-12-09T18:00:00.000", count: 12}],
third: [{timestamp: "2018-12-09T18:00:00.000", count: 5}]
}
Lodash's _.mergeWith()
callback gets the keys as the 3rd param. You can use it to decide how to merge the items:
const object1 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 3}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 2}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 2}]}
const object2 = {first: [{timestamp: "2018-12-09T16:00:00.000", count: 0}], second: [{timestamp: "2018-12-09T17:00:00.000", count: 0}], third: [{timestamp: "2018-12-09T18:00:00.000", count: 3}]}
const mergefn = (...args) =>
_.mergeWith({}, ...args, (o, s, k) => {
if(_.eq(k, 'timestamp')) return new Date(s);
if(_.eq(k, 'count')) return (o || 0) + s;
});
const result = mergefn(object1, object2);
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>