...

View Full Version : Sorting an array by Date Desc



ggeorgiou1982
07-01-2011, 08:18 AM
Hi All.

I have a dynamic Coldfusion form which adds multiple addresses which holds fields like Town, Postcode, ResidentFromDate, ResidentToDate... and on click of the save button I have a script function that runs which I am trying add all the elements of this form into an array and then sort by ResidentFromDate and output the results...

Here is what I have at the minute but my sort does not seem to be working and is throwing out results in the following order (10/2006, 01/2005, 08/2006, 01/2007) and that is clearing not in descending order...

If someone could take a look at my script and tell me what is wrong I would be much appreciated (see below)

* I seem to be getting results and it is just not sorting correctly, so my theory is something is up with the part where I am calling addresses.sort.



var dates = {
convert:function(d) {
// Converts the date in d to a date-object. The input can be:
// a date object: returned without modification
// an array : Interpreted as [year,month,day]. NOTE: month is 0-11.
// a number : Interpreted as number of milliseconds
// since 1 Jan 1970 (a timestamp)
// a string : Any format supported by the javascript engine, like
// "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
// an object : Interpreted as an object with year, month and date
// attributes. **NOTE** month is 0-11.
return (
d.constructor === Date ? d :
d.constructor === Array ? new Date(d[0],d[1],d[2]) :
d.constructor === Number ? new Date(d) :
d.constructor === String ? new Date(d) :
typeof d === "object" ? new Date(d.year,d.month,d.date) :
NaN
);
},
compare:function(a,b) {
// Compare two dates (could be of any type supported by the convert
// function above) and returns:
// -1 : if a < b
// 0 : if a = b
// 1 : if a > b
// NaN : if a or b is an illegal date
// NOTE: The code inside isFinite does an assignment (=).
return (
isFinite(a=this.convert(a).valueOf()) &&
isFinite(b=this.convert(b).valueOf()) ?
(a>b)-(a<b) :
NaN
);
},
inRange:function(d,start,end) {
// Checks if date in d is between dates in start and end.
// Returns a boolean or NaN:
// true : if d is between start and end (inclusive)
// false : if d is before start or after end
// NaN : if one or more of the dates is illegal.
// NOTE: The code inside isFinite does an assignment (=).
return (
isFinite(d=this.convert(d).valueOf()) &&
isFinite(start=this.convert(start).valueOf()) &&
isFinite(end=this.convert(end).valueOf()) ?
start <= d && d <= end :
NaN
);
}
}

// define array
var addresses = [];

// if atAddrSince is greater than 5 years from today
if (atAddrSince > addrFromValidate)
{
// loop round each previous address
for (i=1;i<=maxID;i++)
{
var addrPart = [];

if (eval('document.fmAddPrevAddr.address1'+i))
{
var address1 = eval('document.fmAddPrevAddr.address1'+i+'.value');
var town = eval('document.fmAddPrevAddr.town'+i+'.value');
var country = eval('document.fmAddPrevAddr.country'+i+'.value');
var postcode = eval('document.fmAddPrevAddr.postcode'+i+'.value');
var residentfrom = eval('document.fmAddPrevAddr.ataddrsince'+i+'.value');
var residentto = eval('document.fmAddPrevAddr.ataddrto'+i+'.value');

// insert into array
addrPart[0]=address1;
addrPart[1]=town;
addrPart[2]=country;
addrPart[3]=postcode;
addrPart[4]=residentfromdate;
addrPart[5]=residenttodate;

addresses.push(addrPart);
}
}

addresses.sort(sortfunction)

function sortfunction(a, b)
{
if(dates.compare(a[4],b[4]) == -1)
{
return true;
}
else
{
return false;
}
}

for (var v=0;v<addresses.length;v++)
{
var addresses1 = addresses[v];

alert(addresses1[4]);
}
}


Many Thanks,
George

ggeorgiou1982
07-01-2011, 11:37 AM
Resolved this now with the following code...


// sort address by resident from DESC
addresses.sort(sortfunction)

function sortfunction(a, b)
{
if (a[4] > b[4])
return -1;
else if (a[4] < b[4])
return 1;
else
return 0;
}

Old Pedant
07-01-2011, 10:54 PM
As a minor point...

Using eval( ) is generally considered to be evil.

Instead of doing

if (eval('document.fmAddPrevAddr.address1'+i))
{
var address1 = eval('document.fmAddPrevAddr.address1'+i+'.value');
var town = eval('document.fmAddPrevAddr.town'+i+'.value');
var country = eval('document.fmAddPrevAddr.country'+i+'.value');
var postcode = eval('document.fmAddPrevAddr.postcode'+i+'.value');
var residentfrom = eval('document.fmAddPrevAddr.ataddrsince'+i+'.value');
var residentto = eval('document.fmAddPrevAddr.ataddrto'+i+'.value');
(and so on), you could do


var form = document.fmAddPrevAddr;
if ( form["address1"+i] != null )
{
var address1 = form["address1"+i].value;
var town = form["town"+i].value;
var country = form["country"+i].value;
... etc. ...

siberia-man
07-02-2011, 12:24 AM
The next hint -- convert inputs to Date format when create an object:


function convertToDate(d)
{
// implement the dates.convert function here
};

for (var i = 1; i <= maxID; i++) {
var form = document.fmAddPrevAddr;
var address = {
address1: form['address1' + i].value,
town: form['town' + i].value,
country: form['country' + i].value,
postcode: form['postcode' + i].value,
residentfrom: convertToDate(form['ataddrsince' + i].value),
residentto: convertToDate(form['ataddrto' + i].value)
};
addresses.push(address);
}

// a.residentfrom and b.residentfrom are Date type fields
// comparison of Date type values is performed as Number values
// so the callback function returns
// < 0 - a > b
// = 0 - a == b
// > 0 - a < b
addresses.sort(function(a, b)
{
return b.residentfrom - a.residentfrom;
});



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum