3.11 Sorting an Array of Objects
NN 4, IE 4
3.11.1 Problem
You want to sort an array of objects
based on the value of one of the properties of the objects.
3.11.2 Solution
Sorting an array of objects relies on a logical extension of the
comparison function described for simple arrays in Recipe 3.5. Define
a comparison function as usual, but let the actual comparisons work
on the properties of the objects being passed to the function two at
a time.
To demonstrate the concept, we'll start with the
array of sales objects:
var sales = new Array( );
sales[sales.length] = {period:"q1", region:"east", total:2300};
sales[sales.length] = {period:"q2", region:"east", total:3105};
...
sales[sales.length] = {period:"q4", region"west", total:3810};
If you want to sort the sales array in descending
order of the values of the total properties of
each object, define a comparison function that returns the
appropriate values based on the arithmetic:
function compareTotals(a, b) {
return b.total - a.total;
}
Because each array entry passed as parameters a
and b is an object, you can use those parameter
variables to reference the properties of the objects as they pass
through in waves during the full sort operation. To sort the array by
way of the comparison function, pass the function's
reference to the sort( ) method of the array:
sales.sort(compareTotals);
Recall that the sort( ) method modifies the order
of the original array. But you can invoke other sort(
) methods (that call other comparison functions) to resort
the array by other criteria.
3.11.3 Discussion
Comparison functions can get rather elaborate if necessary. It all
depends on the kind of data in your object properties and what kind
of sorting you need to perform. For example, if an object is defined
with separate properties for month, day, and year, and if you want to
sort the objects by the dates that those numbers represent, the
comparison function can create date objects from those values and
then compare the resulting date objects:
function compareDates(a, b) {
var dateA = new Date(a.year, a.month, a.date);
var dateB = new Date(b.year, b.month, b.date);
return dateA - dateB;
}
If sorting is required of string values in properties, you have to be
more explicit in the comparisons you perform and the values you
return. You may also want to eliminate
case as a factor by comparing values
converted to all upper- or all lowercase characters. The following
function sorts string values of the lastName
property of an array of objects:
function compareNames(a, b) {
var nameA = a.lastName.toLowerCase( );
var nameB = b.lastName.toLowerCase( );
if (nameA < nameB) {return -1}
if (nameA > nameB) {return 1}
return 0;
}
The return values from the function fall into the three categories
described for all array sorting in Recipe 3.5. And because the
toLowerCase( ) method of a string
doesn't disturb the case of the original string, the
object values are ready to be displayed as entered into the data
structure.
3.11.4 See Also
Recipe 3.5 for basic array sorting concepts; Recipe 14.16 for using
object sorting to sort data for rendering in a Dynamic HTML table.
|