123 123 - 7 months ago 15
Javascript Question

Sorting automobiles by multiple criteria

I have a function that is supposed to be able to compare automobiles based on year, type, make etc, but I'm having trouble getting it to work.

I define my automobiles like this:

function Automobile( year, make, model, type ){
this.year = year; //integer (ex. 2001, 1995)
this.make = make; //string (ex. Honda, Ford)
this.model = model; //string (ex. Accord, Focus)
this.type = type; //string (ex. Pickup, SUV)
}

var automobiles = [
new Automobile(1995, "Honda", "Accord", "Sedan"),
new Automobile(1990, "Ford", "F-150", "Pickup"),
new Automobile(2000, "GMC", "Tahoe", "SUV"),
new Automobile(2010, "Toyota", "Tacoma", "Pickup"),
new Automobile(2005, "Lotus", "Elise", "Roadster"),
new Automobile(2008, "Subaru", "Outback", "Wagon")
];


The above part has no issues, but my sorting function has some problems, and I can't figure out what they are. Running this code gives me the error:


Uncaught SyntaxError: Unexpected end of input


/*This function sorts arrays using an arbitrary comparator. You pass it a comparator and an array of objects appropriate for that comparator and it will return a new array which is sorted with the largest object in index 0 and the smallest in the last index*/
function sortArr( comparator, array ){
var sorted = array;
var min; var temp;
for(var i = 0; i < array.length-1; i++){
min = i;
for(var j = i+1; j < array.length; j++){
var comp = comparator(array[j], array[min]);
if(comp)
min = j;
}
if(min != i){
temp = sorted[i];
sorted[i] = sorted[min];
sorted[min] = temp;
}
}
return sorted;
}

function exComparator( int1, int2){
if (int1 > int2){
return true;
} else {
return false;
}
}

/*For all comparators if cars are 'tied' according to the comparison rules then the order of those 'tied' cars is not specified and either can come first*/

/*This compares two automobiles based on their year. Newer cars are "greater" than older cars.*/
function yearComparator( auto1, auto2){
return exComparator(auto1.make, auto2.make);
}

/*This compares two automobiles based on their make. It should be case insensitive and makes which are alphabetically earlier in the alphabet are "greater" than ones that come later.*/
function makeComparator( auto1, auto2){
return exComparator(auto1.make, auto2.make);
}

/*This compares two automobiles based on their type. The ordering from "greatest" to "least" is as follows: roadster, pickup, suv, wagon, (types not otherwise listed). It should be case insensitive. If two cars are of equal type then the newest one by model year should be considered "greater".*/
function typeComparator( auto1, auto2){
var auto1_type = switch(auto1.type.toLowerCase()){
case("roadster"): return 5;
case("pickup"): return 4;
case("suv"): return 3;
case("wagon"): return 2;
case("sedan"): return 1;
}

var auto2_type = switch(auto2.type.toLowerCase()){
case("roadster"): return 5;
case("pickup"): return 4;
case("suv"): return 3;
case("wagon"): return 2;
case("sedan"): return 1;
}

if(auto1_type > auto2_type) {
return auto1.type;
}
else if(auto2_type > auto1_type) {
return auto2.type;
}
else {
if(auto1.year > auto2.year) {
return auto1.type;
}
else {
return auto2.type;
}
}
}

function printArr(array){
for(var i = 0; i < array.length; i++){
var car = array[i];
console.log(car.year + ' ' + car.make + ' ' + car.model + ' ' + car.type);
}
}

Answer

Just some examples for sorting callbacks without switch, but with an hash table instead.

function Automobile(year, make, model, type) {
    this.year = year; //integer (ex. 2001, 1995)
    this.make = make; //string (ex. Honda, Ford)
    this.model = model; //string (ex. Accord, Focus)
    this.type = type; //string (ex. Pickup, SUV)
}

function yearComparator(a, b) {
    return a.year - b.year;
}

function makeComparator(a, b) {
    return a.make.localeCompare(b.make);
}

function modelComparator(a, b) {
    return a.model.localeCompare(b.model);
}

function typeComparator(a, b) {
    var types = { roadster: 5, pickup: 4, suv: 3, wagon: 2, sedan: 1 },
        aa = types[a.type.toLowerCase()] || 0,
        bb = types[b.type.toLowerCase()] || 0;
    return aa - bb;
}

var automobiles = [new Automobile(1995, "Honda", "Accord", "Sedan"), new Automobile(1990, "Ford", "F-150", "Pickup"), new Automobile(2000, "GMC", "Tahoe", "SUV"), new Automobile(2010, "Toyota", "Tacoma", "Pickup"), new Automobile(2005, "Lotus", "Elise", "Roadster"), new Automobile(2008, "Subaru", "Outback", "Wagon")];

automobiles.sort(yearComparator);
document.write('<pre>sorted by year: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
automobiles.sort(makeComparator);
document.write('<pre>sorted by make: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
automobiles.sort(modelComparator);
document.write('<pre>sorted by model: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
automobiles.sort(typeComparator);
document.write('<pre>sorted by type: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');