In my array, I store information about each day as an object. For example:
{day_year: "2012", day_month: "08", day_number: "03", day_name: "mon"}
To enhance the day objects, I have included a timestamp attribute using the following function:
function convertDays() {
var max_i = days.length;
for(var i = 0; i < max_i; i++) {
var tar_i = days[i];
tar_i.timestamp = new Date(tar_i.day_year, tar_i.day_month, tar_i.day_number);
}
}
The order of the days in the array is random without any specific logic.
Now, my goal is to identify the two closest dates to a given date. So, for instance, if my array contains:
- August 2, 2012
- August 4, 2012
- August 23, 2012
And I search for August 11, 2012, I expect it to return August 4, 2012 and August 23, 2012.
I attempted to use a solution from another source which looks like this:
function findClosest(a, x) {
var lo, hi;
for(var i = a.length; i--;) {
if (a[i] <= x && (lo === undefined || lo < a[i])) lo = a[i];
if (a[i] >= x && (hi === undefined || hi > a[i])) hi = a[i];
}
return [lo, hi];
}
However, I encountered issues as it returned unidentified
.
What would be the most efficient way to achieve this while minimizing processor and memory usage?
Edit: "However, how are those results "strange"? Could you provide an example of your code and data?"
I now generate an array of dates using the following approach:
var full_day_array = [];
for(var i = 0; i < 10; i++) {
var d = new Date();
d.setDate(d.getDate() + i);
full_day_array.push({day_year: d.getFullYear().toString(), day_month: (d.getMonth() + 1).toString(), day_number: d.getDate().toString()});
}
Anomalies arise when working with arrays containing more than 10 dates. For example, with a range from August 6, 2012, to August 21, 2012 consisting of 15 dates. When applying
findClosest(full_day_array, new Date("30/07/2012"));
one might predict a result of {nextIndex: 0, prevIndex: -1}
. Surprisingly, it returns {nextIndex: 7, prevIndex: -1}
. Why does this discrepancy occur?
function findClosest(objects, testDate) {
var nextDateIndexesByDiff = [],
prevDateIndexesByDiff = [];
for(var i = 0; i < objects.length; i++) {
var thisDateStr = [objects[i].day_month, objects[i].day_number, objects[i].day_year].join('/'),
thisDate = new Date(thisDateStr),
curDiff = testDate - thisDate;
curDiff < 0
? nextDateIndexesByDiff.push([i, curDiff])
: prevDateIndexesByDiff.push([i, curDiff]);
}
nextDateIndexesByDiff.sort(function(a, b) { return a[1] < b[1]; });
prevDateIndexesByDiff.sort(function(a, b) { return a[1] > b[1]; });
var nextIndex;
var prevIndex;
if(nextDateIndexesByDiff.length < 1) {
nextIndex = -1;
} else {
nextIndex = nextDateIndexesByDiff[0][0];
}
if(prevDateIndexesByDiff.length < 1) {
prevIndex = -1;
} else {
prevIndex = prevDateIndexesByDiff[0][0];
}
return {nextIndex: nextIndex, prevIndex: prevIndex};
}