Reputation: 1181
I have an array of all days of a year like so:
const days = ["2019-01-01", "2019-01-02", "2019-01-03" ...]
And I have an object holding planned and completed tasks for specific days:
const tasks = {"2019-01-01": {"planned": 3, "completed": 2,}, "2019-01-03": { "planned": 1, "completed": 0 }, "2019-01-10": { "planned": 1, "completed": 1} ... }
What I want is a new object that contains for all days information if tasks were planned and completed or not, like so:
const tasksNew = {"2019-01-01": {"planned": 3, "completed": 2}, "2019-02-02": {"planned": 0, "completed": 0} ...}
I know this somehow works with reduce but I can't help myself at the moment.
Upvotes: 3
Views: 4741
Reputation: 51
shortest way:
{...days.reduce((obj,d)=>({...obj,[d]:{ planned: 0, completed: 0 }}),{}), ...tasks}
Upvotes: 0
Reputation: 50684
You can use reduce
to essentially map the days
array to the keys in the tasks
object. Here I loop through every day in days
, check if it is in the tasks
object. If it is I add the current day
as the key and its associated object from tasks
to the newTasks
object. If the day
isn't in the object, then I add the default complete: 0
and planned: 0
to the appended array:
const days = ["2019-01-01", "2019-01-02", "2019-01-03"],
tasks = {
"2019-01-01": {
"planned": 3,
"completed": 2,
},
"2019-01-03": {
"planned": 1,
"completed": 0
},
"2019-01-10": {
"planned": 1,
"completed": 1
}
},
newTasks = days.reduce((acc, day) =>
day in tasks ?
{...acc, [day]: tasks[day]} :
{...acc, [day]: {planned: 0, complete: 0}
}, {});
console.log(newTasks);
Upvotes: 1
Reputation: 36564
clone the tasks
. Store keys
of tasks
in a variable. Then loop through days
check if keys
doesnot includes()
day
add it the the object newTasks
const days = ["2019-01-01", "2019-01-02", "2019-01-03"]
const tasks = {"2019-01-01": {"planned": 3, "completed": 2,}, "2019-01-03": { "planned": 1, "completed": 0 }, "2019-01-10": { "planned": 1, "completed": 1}}
const newTasks = JSON.parse(JSON.stringify(tasks));
const keys = Object.keys(tasks);
days.forEach(day => {
if(!keys.includes(day))
newTasks[day] = {completed:0,planned:0}
}
)
console.log(newTasks)
Upvotes: 0
Reputation: 13964
Use reduce
on your days
array. For each day, it an entry is found in your tasks
object, add this entry to the accumulator, otherwise, return a default entry.
Here is the MDN doc on Array.reduce().
const days = ["2019-01-01", "2019-01-02", "2019-01-03"];
const tasks = {"2019-01-01": {"planned": 3, "completed": 2,}, "2019-01-03": { "planned": 1, "completed": 0 }, "2019-01-10": { "planned": 1, "completed": 1} };
const tasksNew = days.reduce((accum, day) => {
accum[day] = tasks[day] ? tasks[day] : { planned: 0, completed: 0 };
return accum;
}, {});
console.log(tasksNew);
Upvotes: 5
Reputation: 3725
You can reduce your days array creating a new object. For each day, you'll check if there are a tasks for that day and merge them to your result map, if there are no tasks for that day, merge a default empty "indicator":
const days = [
"2019-01-01",
"2019-01-02",
"2019-01-03",
"2019-01-04",
"2019-01-07",
"2019-01-08",
"2019-01-09",
"2019-01-10"
]
const DEFAULT = { "planned": 0, "completed": 0 }
const tasks = {
"2019-01-01": {"planned": 3, "completed": 2,},
"2019-01-03": { "planned": 1, "completed": 0 },
"2019-01-10": { "planned": 1, "completed": 1 }
}
const result = days.reduce(
(map, day) =>
Object.assign({}, map, { [day]: tasks[day] ? tasks[day] : DEFAULT }),
{}
)
console.log(result)
Upvotes: 2
Reputation: 1949
const taskNew = days.reduce((acc, day) => {
if (!tasks[day]) {
return {
...acc,
[day]: {
planned: 0,
completed: 0
}
}
}
return {
...acc,
[day]: tasks[day]
}
}, {});
for details about reduce: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/reduce
Upvotes: 3