I have list of statuses where not started is the minimum , followed by submitted and last is complete.
So if we apply the logic on the data since there are 2 status on the current array of object below which are "Not Started" and "Submitted" so the function should return Not Started because not started is the min.
If there is only 1 item in an array then get the only status as a result.
How do we filter the array of objects and get the min based on the order in statuses array. Thanks for any idea.
#currentCode
getMin(id:number , key:string) {
let data = [
{
"id": 14,
"status": "Submitted",
},
{
"id": 15,
"status": "Not Started",
}
]
let min = Math.min(...data.map(item => item.status));
console.log('result' , min)
}
#order of statuses
statuses: any[] = [
{ viewValue: 'Not Started', value: 1 },
{ viewValue: 'Submitted', value: 2 },
{ viewValue: 'Complete', value: 3 },
]
#sample array of objects - result Not Started
data = [
{
"id": 14,
"status": "Submitted",
},
{
"id": 15,
"status": "Not Started",
}
]
#sample array of objects - result Submitted
data = [
{
"id": 14,
"status": "Submitted",
},
{
"id": 17,
"status": "Complete",
}
]
#sample array of objects - result Complete , since there is only 1 get the only status
data = [
{
"id": 17,
"status": "Complete",
}
]
CodePudding user response:
You need to look up the status from data
in your statuses
array.
const data = [
{
"id": 14,
"status": "Submitted",
},
{
"id": 17,
"status": "Complete",
}
];
const statuses = [
{ viewValue: 'Not Started', value: 1 },
{ viewValue: 'Submitted', value: 2 },
{ viewValue: 'Complete', value: 3 },
]
let min = Math.min(...data.map(item => statuses.find(st => st.viewValue === item.status).value));
let minStatus = statuses.find(st => st.value === min).viewValue;
console.log(minStatus);
CodePudding user response:
A straightforward solution is to simply sort the array by statuses
value, which then gives you access to the complete ordering, and the entire object for each position. Here first mapping the statuses
array to an object keyed by viewValue
to directly access status values.
const data = [
{ "id": 14, "status": "Submitted", },
{ "id": 17, "status": "Complete", },
{ "id": 15, "status": "Not Started", },
{ "id": 15, "status": null, }
];
const statuses = [
{ viewValue: 'Not Started', value: 1 },
{ viewValue: 'Submitted', value: 2 },
{ viewValue: 'Complete', value: 3 },
];
const statusMap = Object.fromEntries(statuses
.map(({ viewValue, value }) => [viewValue, value])
);
const sorted = data
.filter(d => Object.hasOwn(statusMap, d.status))
.sort((a, b) => statusMap[a.status] - statusMap[b.status]);
const min = sorted.at(0);
const max = sorted.at(-1);
console.log('min:', min.status);
console.log('max:', max.status);
// or the complete objects
console.log({ min, max })
Edit
Added a filter()
call before sorting to remove datum that don't have a status that appears in statusMap
using Object.hasOwn
. This also makes the original spread redundant since filter()
returns a new array thus avoiding mutation of the original data
array with the sort()
call.