I have an array of subscriptions group by the type (basic,medium ...)
`
[
[
"Basic",
[
{ "id": 2, "name": "Basic", "started_at": "2022-01-24", "count": 4 },
{ "id": 2, "name": "Basic", "started_at": "2022-03-16", "count": 2 },
{ "id": 2, "name": "Basic", "started_at": "2022-05-16", "count": 1 }
]
],
[
"Medium",
[
{ "id": 3, "name": "Medium", "started_at": "2022-02-21", "count": 1 },
{ "id": 3, "name": "Medium", "started_at": "2022-05-28", "count": 1 }
]
],
[
"Premium",
[{ "id": 4, "name": "Premium", "started_at": "2022-04-21", "count": 1 }]
],
[
"Master",
[
{ "id": 7, "name": "Master", "started_at": "2022-07-28", "count": 1 },
{ "id": 7, "name": "Master", "started_at": "2022-08-02", "count": 1 }
]
],
[
"Jedi",
[{ "id": 6, "name": "Jedi", "started_at": "2022-09-28", "count": 1 }]
]
]
`
What I want to do is return an array containing objects foreach sub with the following data(get the count value by month):
`
[
{
label: "Basic",
data: [4, 0, 2, 0, 1,0],
},
{
label: "Medium",
data: [0, 1, 0, 0, 1,0],
},
...
]
`
The data field should contain the count field foreach subscription corresponding to the month. For example for with count 4 in January and count 2 in March it will return [4,0,1] with 0 for February.
How can I achieve that ?
I did this but it's returning only the existing month values so there is no way to know which month that value is for.
subscriptions.map((item) => {
return {
label: item[0],
data: item[1].map((value, index) => {
return value.count;
}),
};
})
You could reduce the array and create a mapper object which maps each plan with month specifc count. Something like this:
{
"Basic": {
"1": 4,
"3": 2,
"5": 1
},
"Medium": {
"2": 1,
"5": 1
},
...
}
Then loop through the entries of the object and create objects with plan as label and an array of length: 12 and get the data for that specific month using the index
const input=[["Basic",[{id:2,name:"Basic",started_at:"2022-01-24",count:4},{id:2,name:"Basic",started_at:"2022-03-16",count:2},{id:2,name:"Basic",started_at:"2022-05-16",count:1}]],["Medium",[{id:3,name:"Medium",started_at:"2022-02-21",count:1},{id:3,name:"Medium",started_at:"2022-05-28",count:1}]],["Premium",[{id:4,name:"Premium",started_at:"2022-04-21",count:1}]],["Master",[{id:7,name:"Master",started_at:"2022-07-28",count:1},{id:7,name:"Master",started_at:"2022-08-02",count:1}]],["Jedi",[{id:6,name:"Jedi",started_at:"2022-09-28",count:1}]]];
const mapper = input.reduce((acc, [plan, subscriptions]) => {
acc[plan] ??= {}
for(const { started_at, count } of subscriptions)
acc[plan][+started_at.slice(5,7)] = count
return acc;
}, {})
const output =
Object.entries(mapper)
.map( ([label, subData]) => ({
label,
data: Array.from({ length: 12 }, (_, i) => subData[i+1] ?? 0)
}) )
console.log(output)
Note:
This assumes that the data is for a single year only. If it can be across years you'd have to create another level of nesting:
{
"Basic": {
"2022": {
"1": 3
}
}
}
started_at.slice(5,7) is used to get the month number. If the dates are not in the ISO 8601 format, you can use new Date(started_at).getMonth() + 1 to get the month part.
This question already has answers here:
Remove property for all objects in array
(18 answers)
Closed 3 months ago.
I have the following array of objects. I wanted to make new array of object excluding date field.
The new array should return as follows:
const new_arr = [
{
"id": 1,
"user": 0
},
{
"id": 2,
"user": 0
}
]
What's my mistake here?
const arr = [{
"id": 1,
"date": 0,
"user": 0
},
{
"id": 2,
"date": 0,
"user": 0
}
]
const new_arr = arr.filter((items) => !items.date)
console.log(new_arr);
you can use map
like this
const arr = [
{
"id": 1,
"date": 0,
"user": 0
},
{
"id": 2,
"date": 0,
"user": 0
}
]
console.log(arr.map(({date, ...rest}) => ({...rest})))
This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Closed 1 year ago.
I have an object:
[
{
"id": 10,
"name": "comedy"
},
{
"id": 12,
"name": "documentary"
},
{
"id": 11,
"name": "scifi"
}
]
I need to take only the id values and add them into 1 array like so:
[ 10, 12, 13 ]
or
{ 10, 12, 13 }
I am trying:
const getIDs = value.map( ( { id } ) => ( {
id: id
} ) );
But it creates:
[
{
"id": 10
},
{
"id": 12
},
{
"id": 11
}
]
Inside the map just return the id values instead of objects
Here is the quick solution
const values = [
{
"id": 10,
"name": "comedy"
},
{
"id": 12,
"name": "documentary"
},
{
"id": 11,
"name": "scifi"
}
]
const getIDs = values.map(({id}) => id);
console.log(getIDs)
I have an array of object and I want to copy that array of object to another array while modifying some items, like copying id only by ascending order and copying only the value of trophies of basketball to trophies. How to do it?
const item = [{
"id": 33,
"name": "John"
"trophies": {
"basketball" : 2,
"baseball" : 5
},
"profile": "profile/212"
}
{
"id": 12,
"name": "Michael"
"trophies": {
"basketball" : 6,
"baseball" : 7
},
"profile": "profile/341"
}
]
I want the above array of object after copying to look something like
const item2 = [{
"id": 12,
"name": "Michael"
"trophies": 6,
"profile": "http://collegeprofile.com/profile/341"
},
{
"id": 33,
"name": "John"
"trophies": 2,
"profile": "http://collegeprofile.com/profile/212"
}
]
You can sort by id ascending order using Array.prototype.sort
And map basketball value to trophies using Array.prototype.map.
const item = [{
"id": 33,
"name": "John",
"trophies": {
"basketball": 2,
"baseball": 5
},
"profile": "profile/212"
}, {
"id": 12,
"name": "Michael",
"trophies": {
"basketball": 6,
"baseball": 7
},
"profile": "profile/341"
}];
const output = item.sort((a, b) => (a.id - b.id)).map((item) => ({
...item,
trophies: item.trophies.basketball,
profile: "http://collegeprofile.com/" + item.profile
}));
console.log(output);
This question already has answers here:
Group objects by property in javascript
(8 answers)
Closed 2 years ago.
let attributeSet = [{
"id": 1,
"value": 11
},
{
"id" : 1,
"value": 12
},
{
"id" : 1,
"value" : 13
},
{
"id": "2",
"value" : "Qwerty"
}
]
I want to combine all the value in values like this
attributeSet = [
{
"id": 1,
"value": [11, 12, 13]
},
{
"id": 2,
"value": "Qwerty"
}
]
I am using two for loops for comparing the ids and then pushing it into an array. Can someone suggest me any better way.
You can use reduce & inside callback check if the accumulator object have the key same as id of the object under iteration. If not then create the key and push value to it
let attributeSet = [{
"id": 1,
"value": 11
},
{
"id": 1,
"value": 12
},
{
"id": 1,
"value": 13
},
{
"id": "2",
"value": "Qwerty"
}
]
let newData = attributeSet.reduce((acc, curr) => {
if (!acc[curr.id]) {
acc[curr.id] = {
id: curr.id,
value: []
}
}
acc[curr.id].value.push(curr.value)
return acc;
}, {});
console.log(Object.values(newData))