Ok i have an array as following
const services = [
{
"data":[
{
"duration":{
"start":"10",
"end":"11"
},
"serviceId":215
},
{
"duration":{
"start":"4",
"end":"5"
},
"serviceId":37
},
],
"title":"1632767400000"
},
{
"data":[
{
"duration":{
"start":"9",
"end":"11"
},
"serviceId":215
},
{
"duration":{
"start":"2",
"end":"3"
},
"serviceId":37
},
],
"title":"1632767400000"
},
]
As you can see i have anoth array (data
) inside my main array which has multiple objects.
i want to filter these data, for example i want to get data which has start and end duration inbetween 9 and 11.
So my final output of the filtered data must be as follows
const services = [
{
"data":[
{
"duration":{
"start":"10",
"end":"11"
},
"serviceId":215
},
],
"title":"1632767400000"
},
{
"data":[
{
"duration":{
"start":"9",
"end":"11"
},
"serviceId":215
},
],
"title":"1632767400000"
},
]
I have tried something like the following
const test = services.map((item) => {
return item.data.filter((service) => {
return (
parseInt(service.duration.start) >=
9 &&
parseInt(service.duration.end) <=
11
);
});
});
But it only returns the data
elements array and not the full array like i need. How do i filter data
arrays in my main array and keep the original structure of the main array.
FYI: any lodash solutions are welcome too.
CodePudding user response:
services
is an array of objects, so first you have to map over the array and return an object will all properties as ...o
and data
with filtered objects whose duration.start <= 11
services.map((o) => ({
...o,
data: o.data.filter(
(obj) => obj.duration.start >= 9 && obj.duration.end <= 11
),
}));
const services = [
{
data: [
{
duration: {
start: "10",
end: "11",
},
serviceId: 215,
},
{
duration: {
start: "4",
end: "5",
},
serviceId: 37,
},
],
title: "1632767400000",
},
{
data: [
{
duration: {
start: "9",
end: "11",
},
serviceId: 215,
},
{
duration: {
start: "2",
end: "3",
},
serviceId: 37,
},
],
title: "1632767400000",
},
];
const result = services.map((o) => {
return {
...o,
data: o.data.filter((obj) => obj.duration.start >= 9 && obj.duration.end <= 11),
};
});
console.log(result);
CodePudding user response:
Your response data is dealing only with the data
node in the services array.
Debugging your map function
services.map((item) => {
return item.data.filter((service) => {
return (
parseInt(service.duration.start) >=
9 &&
parseInt(service.duration.end) <=
11
);
});
});
Your map function loops through services
array. On looping the array it filters the data node and check the condition and returns the data nodes which satisfies that condition. Please Note it reurns only the data nodes
You have to send not just the data nodes, it should use the all the nodes in each objects of services
array. This can be done using spread operator like {data, ...restNodes}
. Here the each object from services
array will be splitted into two set. The data
node from each object of will be available in the variable called data
and rest all variables will be available in restNodes
variable.
So in map, return the filter action on the data
node aswell as the restNodes
variable. So this will give all the data in each nodes from services
array and filtered data from data
node.
const services = [
{
"data": [
{ "duration": { "start": "10", "end": "11" }, "serviceId": 215 },
{ "duration": { "start": "4", "end": "5" }, "serviceId": 37 },
],
"title": "1632767400000"
},
{
"data": [
{ "duration": { "start": "9", "end": "11" }, "serviceId": 215 },
{ "duration": { "start": "2", "end": "3" }, "serviceId": 37 },
],
"title": "1632767400000"
},
];
const output = services.map(({data, ...restNodes}) => {
return {
data: data.filter((service) => {
return (
parseInt(service.duration.start) >=
9 &&
parseInt(service.duration.end) <=
11
);
}),
...restNodes,
};
});
console.log(output);