I use an ajax call to get data on grades based on a 12-month date range. Then I calculate the ratio of passes and fails by looping through a for loop of the dates and a nested for loop of the data. If the date and the data's date match, perform calculations for that date.
The problem is that I loop through a list of 12 with a nested for loop of up to thousands. The algorithm therefore seems to have an efficiency of x^2. How can I improve the efficiency of this algorithm? Can it be improved to 2x?
dataSet = [];
dateList = [
01 - 2023,
02 - 2023,
//...
12 - 2023,
];
$.ajax({
url: '...',
type: 'GET',
global: false,
success: function(data) {
// Iterate through each date
for (date of dateList) {
var passes = 0;
var fails = 0;
var passFailRatio = 0;
// Iterate through each data result
for (result of data['results']) {
//If data's grade date matches with date increment pass or fail
if (result.gradeDate == date) {
if (result.pass == true) {
passes++;
} else if (result.fail == true) {
fails++;
}
}
}
if ((passes + fails) == 0) {
passFailRatio = 0;
} else {
passFailRatio = (100 * (passes / (passes + fails))).toFixed(0);
}
// Push a dictionary to a list based on the date
dataSet.push({
'date': date,
'passFailRatio': passFailRatio
});
}
}
});
I was thinking about creating the list of dates while iterating through the data results. If the data result has a unique grade date, then add that date to the list and increment passes and fails for that date.
The algorithm as written has complexity O(n*m), with n
being the length of dateList
and m
being the length of data[results]
.
You can improve this by sorting both lists, followed by a standard merge.
The sort/merge complexity is:
Merging the two sorted lists is, in pseudo-code (you'll have to convert to JavaScript):
dateIdx = 0
rsltIds = 0
passes = 0
fails = 0
while (dateIdx < length(datelist) and rsltIdx < length(results))
{
if (results[rsltIdx].gradeDate < datelist[dateIdx])
{
// skip this result because there's no matching date
++rsltIdx;
} else if (results[rsltIdx].gradeDate == dateList[dateIdx])
{
if (results[rsltIdx].pass)
++passes;
else
++fails;
++rsltIdx;
} else
{
// result date is greater. Compute ratio for this date.
if (passes + fails) == 0
passFailRatio = 0;
else
passFailRatio = (100 * (passes / (passes + fails))).toFixed(0);
// Push a dictionary to a list based on the date
dataSet.push({
'date': datelist[dateIdx],
'passFailRatio': passFailRatio
});
passes = 0;
fails = 0;
// and go to the next date
++dateIdx;
}
}
// Output '0' entries for any remaining dates
while (dateIdx < length(dateList))
{
dataSet.push({
'date': datelist[dateIdx],
'passFailRatio': 0
});
}
// Don't care about remaining results because there is no
// corresponding dateList entry for them.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.