I am solving the problem as follows:
I have an array of objects with input format:
let allTasks = [
{
time: "07-2020",
tasks: [
{
code: "p1",
value: 1111
}
],
},
{
time: "07-2020",
tasks: [
{
code: "p2",
value: 2222
}
]
},
{
time: "08-2020",
tasks: [
{
code: "p1",
value: 3333
}
]
},
{
time: "08-2020",
tasks: [
{
code: "p2",
value: 4444
}
]
},
{
time: "09-2020",
tasks: [
{
code: "p1",
value: 5555
}
]
},
{
time: "09-2020",
tasks: [
{
code: "p2",
value: 6666
}
]
},
]
I want to convert into a format that is formatted as follows:
output = [
{
p1: [
["07-2020",1111],
["08-2020",3333],
["09-2020",5555],
]
},
{
p2: [
["07-2020",2222],
["08-2020", 4444],
["09-2020", 6666],
]
},
// ... p3, p4....
]
I use reduce() method to group the objects in an array.
let newArr = [];
allTasks.forEach((x,index)=>{
newArr.push({
tasks: x.tasks.map(y=>Object.assign(y,{time: x.time}))
})
})
console.log('newArr',newArr);
let listTask = newArr.flatMap(x=>x.tasks);
let groupData = listTask.reduce((gr,item)=>{
gr[item.code] = [...gr[item.code] || [],item];
return gr;
},[])
let newGroupData = Object.entries(groupData).map(([key,data])=>{
console.log('-------------------------')
let result = Object.values(data.reduce((arr,item)=>{
arr[item.time] = arr[item.time] || [item.time];
arr[item.time].push(item.value);
return arr;
},[]));
return {
[key]: result
}
})
console.log('newGroupData',newGroupData)
The results have been expected as above. But my code is long, how do I refactor my code and is there a better way to do it ?
Please help me.
Thank you!
A different approach
You could flatten the tasks first, with complemented key-value pair of time. To array of this
[
...
{ code: 'p1', value: 1111, time: '07-2020' }
...
]
After that, group task by code and do some manipulation with the grouped to achieve your expected result
const groupByCode = {}
allTasks
.flatMap((parentTask) =>
parentTask.tasks.map((task) => ({ ...task, time: parentTask.time }))
)
.forEach((flattenedTask) => {
if (groupByCode[flattenedTask.code]) {
groupByCode[flattenedTask.code].push(flattenedTask)
} else {
groupByCode[flattenedTask.code] = [flattenedTask]
}
})
const res = Object.entries(groupByCode).map(([code, tasks]) => ({
[code]: tasks.map((task) => [task.time, task.value]),
}))
Full implementation
let allTasks = [
{
time: "07-2020",
tasks: [
{
code: "p1",
value: 1111,
},
],
},
{
time: "07-2020",
tasks: [
{
code: "p2",
value: 2222,
},
],
},
{
time: "08-2020",
tasks: [
{
code: "p1",
value: 3333,
},
],
},
{
time: "08-2020",
tasks: [
{
code: "p2",
value: 4444,
},
],
},
{
time: "09-2020",
tasks: [
{
code: "p1",
value: 5555,
},
],
},
{
time: "09-2020",
tasks: [
{
code: "p2",
value: 6666,
},
],
},
]
const groupByCode = {}
allTasks
.flatMap((parentTask) =>
parentTask.tasks.map((task) => ({ ...task, time: parentTask.time }))
)
.forEach((flattenedTask) => {
if (groupByCode[flattenedTask.code]) {
groupByCode[flattenedTask.code].push(flattenedTask)
} else {
groupByCode[flattenedTask.code] = [flattenedTask]
}
})
const res = Object.entries(groupByCode).map(([code, tasks]) => ({
[code]: tasks.map((task) => [task.time, task.value]),
}))
console.log(JSON.stringify(res, null, 2))
Reference
Array.prototype.flatMap()
Object.entries()
Related
I have a structure like
const test = [
{
items: [
{
id: "tete",
},
{
id: "tete",
},
],
},
{
items: [
{
id: "tete",
},
],
},
];
How go i get all the 'id' value from these array using javascript.
The new flatMap can do it all in one line with the regular map:
const test = [{items:[{id:"tete",},{id:"tete",},],},{items:[{id:"tete"}]}];
const result = test.flatMap((e) => e.items.map((i) => i.id));
console.log(result);
It is equivalent to the following:
const result = test.map((e) => e.items.map((i) => i.id)).flat();
This is one option to extract the id values:
const test = [
{
items: [
{
id: "tete",
},
{
id: "tete",
},
],
},
{
items: [
{
id: "tete",
},
],
},
];
const ids = test.reduce((acc, element) => {
for (const item of element.items) {
acc.push(item.id);
}
return acc;
}, []);
console.log(ids);
I have to organise the array, Getting a response array like this
let data = [
{
date: "2022-07-01T07:26:22",
tips: [
{ id: 1 }
]
},
{
date: "2022-07-01T12:05:55",
tips: [
{ id: 1 }
]
},
{
date: "2022-07-05T13:09:16",
tips: [
{ id: 1 }
]
},
{
date: "2022-07-05T13:31:07",
tips: [
{ id: 1 }
]
},
{
date: "2022-06-29T09:21:26",
tips: [
{ id: 1 }
]
}
]
The desired output :
let data = [
{
'2022-07-01': [
{
tips: [
{ id: 1 }
]
},
{
tips: [
{ id: 1 }
]
},
]
},
{
'2022-07-05': [
{
tips: [
{ id: 1 }
]
},
{
tips: [
{ id: 1 }
]
},
]
},
{
'2022-06-29': [
{
tips: [
{ id: 1 }
]
},
]
}
]
I need to get data with the same key in the above array format. I have tried different ways to achieve this but have not gotten the proper result Which is the best way to get the desired output.
Thanks in advance!!!
Here is a solution using reduce. Grouping first using reduce and after that getting the values of the object using Object.values
let data = [ { date: "2022-07-01T07:26:22", tips: [ { id: 1 } ] }, { date: "2022-07-01T12:05:55", tips: [ { id: 1 } ] }, { date: "2022-07-05T13:09:16", tips: [ { id: 1 } ] }, { date: "2022-07-05T13:31:07", tips: [ { id: 1 } ] }, { date: "2022-06-29T09:21:26", tips: [ { id: 1 } ] }]
let res = Object.values(data.reduce((acc,{date,tips})=>{
let key = date.substring(0,10)
acc[key] = acc[key] || {[key]:[]}
acc[key][key].push({tips})
return acc
},{}))
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have a nested array . I want to take values from array and push to new single object.
should read take the _id as object key and category array field should be value for _id
const Ll = [
{
_id: 'milk',
category: [
[
{
name: 'Alfred',
job: 'manager'
},
{
name: 'Mark',
job: 'manager'
}
]
]
},
{
_id: 'grocery',
category: [
[
{
name: 'William',
job: 'manager'
}
]
]
}
]
I want object like so,
const obj = {
milk: [
{
name: 'Alfred',
job: 'manager'
},
{
name: 'Mark',
job: 'manager'
}
],
grocery: [
{
name: 'William',
job: 'manager'
}
]
}
Is possible to do
Thanks!
You could do it using Array.prototype.reduce() method. Traverse the array and group it by _id.
const data = [
{
_id: 'milk',
category: [
[
{
name: 'Alfred',
job: 'manager',
},
],
],
},
{
_id: 'grocery',
category: [
[
{
name: 'William',
job: 'manager',
},
],
],
},
{
_id: 'milk',
category: [
[
{
name: 'Mark',
job: 'manager',
},
],
],
},
];
const ret = data.reduce((prev, c) => {
const p = prev;
const key = c._id;
p[key] = p[key] ?? [];
p[key].push(...c.category.flat());
return p;
}, {});
console.log(ret);
ES6:
const data = [
{
_id: 'milk',
category: [
[
{
name: 'Alfred',
job: 'manager',
},
],
],
},
{
_id: 'grocery',
category: [
[
{
name: 'William',
job: 'manager',
},
],
],
},
{
_id: 'milk',
category: [
[
{
name: 'Mark',
job: 'manager',
},
],
],
},
];
const ret = data.reduce((prev, c) => {
const p = prev;
const key = c._id;
p[key] = p[key] || [];
p[key].push(...c.category.reduce((acc, val) => acc.concat(val), []));
return p;
}, {});
console.log(ret);
Here is solution for you.
const obj = {};
data.forEach(d => {
const categories = d.category.reduce((a, v) => a.concat(v), []);
obj[d._id] = obj[d._id] ? [...obj[d._id], ...categories] : [...categories];
});
console.log(obj);
You could use reduce with empty object accumulated
Technique combined with:
computed property [_id]: category
object destruction (acc, { _id, category }) as well as ({...acc})
const data = [ { _id: "milk", category: [ [ { name: "Alfred", job: "manager", }, { name: "Mark", job: "manager", }, ], ], }, { _id: "grocery", category: [ [ { name: "William", job: "manager", }, ], ], }, ];
const res = data.reduce(
(acc, { _id, category }) => ({ ...acc, [_id]: category.flat() }),
{}
);
console.log(res);
const keys = [...new Set(data.map(item => item._id))];
const newObj = keys.reduce((acc, curr) => {
const value = data.filter(({ _id }) => _id === curr).map(({ category }) => {
return {
...category[0][0]
}
});
return {
...acc,
[curr]: value
}
}, {});
After I use reduce() to group the objects in an array by month-year:
let groupByMonth;
if (newlistTaskEvaluation) {
groupDataByMonth = newlistTaskEvaluation.reduce((groups, item) => {
groups[item.time] = [...groups[item.time] || [], item];
return groups;
}, {});
}
I have an array of event objects formatted by group month-year as follows:
groupByMonth = {
'7-2020': [ //july
{
time: "7-2020",
task: [
{ code: "p1", value: 123 },
{ code: "p2", value: 234 },
]
},
{
time: "7-2020",
task: [
{ code: "p1", value: 345 },
{ code: "p2", value: 456 },
]
},
],
'8-2020': [ //august
{
time: "8-2020",
task: [
{ code: "p1", value: 567 },
{ code: "p2", value: 678 },
]
},
{
time: "8-2020",
task: [
{ code: "p1", value: 789 },
{ code: "p2", value: 999 },
]
},
]
}
How to group object of Array by key 'code', time and total sum by value?
Expected result:
output = [
{
time: "7-2020", //total month 7-2020
task: [
{ code: "p1", valueSum: 468 }, // 123 + 345
{ code: "p2", valueSum: 690 }, // 234 +456
]
},
{
time: "8-2020",
task: [
{ code: "p1", valueSum: 1356 }, // 567 + 789
{ code: "p2", valueSum: 1677 }, // 999 +678
]
}
]
Please help me.
You could try something like this
const output = Object.entries(groupByMonth).map(([time, datapoints]) => {
const codes = {}
const allTasks = datapoints.flatMap(point => point.task)
for (const { code, value } of allTasks) {
codes[code] = (codes[code] || 0) + value
}
return {
time,
tasks: Object.entries(codes).map(([code, value]) => ({ code, value }))
}
}
Though one downside is that the time complexity isn't perfect because of the structure of the data
const groupByMonth = {
"7-2020": [
//july
{
time: "7-2020",
task: [
{ code: "p1", value: 123 },
{ code: "p2", value: 234 },
],
},
{
time: "7-2020",
task: [
{ code: "p1", value: 345 },
{ code: "p2", value: 456 },
],
},
],
"8-2020": [
//august
{
time: "8-2020",
task: [
{ code: "p1", value: 567 },
{ code: "p2", value: 678 },
],
},
{
time: "8-2020",
task: [
{ code: "p1", value: 789 },
{ code: "p2", value: 999 },
],
},
],
};
const result = Object.keys(groupByMonth).reduce((arr, key)=>{
const task = (groupByMonth[key]).reduce((acc, rec) => {
return [...acc, rec.task]
}, [])
const newObj = {time: key, task}
return [...arr, newObj]
}, [])
console.log(JSON.stringify(result, 2, 2))
You can get object's keys and when you iterate over them find out inner objects, then, in every object use another oner reduce to get tasks in that data-type what you need.
for iterations i suddenly use reduce() method as a swiss-knife to working with arrays.
Currently I have two different array of objects and my end result is I am trying to have one single array of objects.
const postIds = [
{ id: 4938960132 },
{ id: 5586491011 },
{ id: 4671908225 },
{ id: 4594788047 },
{ id: 4657970305 }
]
const images = [
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/rustic20coffee20table.jpeg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Amazing-Table-For-Flamboyant-Furniture-Home-Design-Ideas-With-Rustic-Furniture-Coffee-Table.jpg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/envoy-lookout-rooftop-11b-780x520.jpg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Alexanderplatz_03.jpg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/mountain-landscape-wallpaper-29048-29765-hd-wallpapers.jpg%3Ft=1528912781831-6.jpeg' }
]
What I am hoping to have at the end is a data structure like the following
const newData = [
{ id: 4938960132, featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/rustic20coffee20table.jpeg%3Ft=1528912781831-6.jpeg' },
{ id: 5586491011, featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Amazing-Table-For-Flamboyant-Furniture-Home-Design-Ideas-With-Rustic-Furniture-Coffee-Table.jpg%3Ft=1528912781831-6.jpeg' },
{ id: 4671908225, featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/envoy-lookout-rooftop-11b-780x520.jpg%3Ft=1528912781831-6.jpeg' },
{ id: 4594788047, featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/mountain-landscape-wallpaper-29048-29765-hd-wallpapers.jpg%3Ft=1528912781831-6.jpeg'},
{ id: 4657970305, featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/mountain-landscape-wallpaper-29048-29765-hd-wallpapers.jpg%3Ft=1528912781831-6.jpeg' }
]
I've been trying a lot of different things here such as reduce, spread operator and other es6 functions but cannot seem to get the data structure that I am looking for.
Any help would be much appreciated
Assuming the two arrays have the same length:
const newData = [...postIds.map((postId, i) => Object.assign({}, postId, images[i]))];
Alternativelly, with ... operator:
const newData = [...postIds.map((item, i) => {
return {
...item,
...images[i]
};
})];
Working snippet:
const postIds = [
{ id: 4938960132 },
{ id: 5586491011 },
{ id: 4671908225 },
{ id: 4594788047 },
{ id: 4657970305 }
]
const images = [
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/rustic20coffee20table.jpeg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Amazing-Table-For-Flamboyant-Furniture-Home-Design-Ideas-With-Rustic-Furniture-Coffee-Table.jpg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/envoy-lookout-rooftop-11b-780x520.jpg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Alexanderplatz_03.jpg%3Ft=1528912781831-6.jpeg' },
{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/mountain-landscape-wallpaper-29048-29765-hd-wallpapers.jpg%3Ft=1528912781831-6.jpeg' }
]
const newData = [...postIds.map((item, i) => Object.assign({}, item, images[i]))];
console.log(newData)
You creduce both array by mapping the objects at the same index and by assigning to a new object.
This works for an arbitrary count of arrays.
const
postIds = [{ id: 4938960132 }, { id: 5586491011 }, { id: 4671908225 }, { id: 4594788047 }, { id: 4657970305 }],
images = [{ featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/rustic20coffee20table.jpeg%3Ft=1528912781831-6.jpeg' }, { featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Amazing-Table-For-Flamboyant-Furniture-Home-Design-Ideas-With-Rustic-Furniture-Coffee-Table.jpg%3Ft=1528912781831-6.jpeg' }, { featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/envoy-lookout-rooftop-11b-780x520.jpg%3Ft=1528912781831-6.jpeg' }, { featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/Alexanderplatz_03.jpg%3Ft=1528912781831-6.jpeg' }, { featuredImage: 'https://www.rusticfurnitureboston.com/hubfs/Blog_Media/mountain-landscape-wallpaper-29048-29765-hd-wallpapers.jpg%3Ft=1528912781831-6.jpeg' }],
result = [images, postIds].reduce(
(r, a) => a.map((o, i) => Object.assign({}, o, r[i])),
[]
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }