views:

43

answers:

3
function Player() {
  var score;

  this.getScore = function() { return score; }
  this.setScore = function(sc) { score = sc; }
}

function compare(playerA, playerB) {
  return playerA.getScore() - playerB.getScore();
}

var players = [];

players['player1'] = new Player();
players['player2'] = new Player();

Array(players).sort(compare);

I have code that is similar to the above. When I step through the code with a debugger, the compare function never gets called and the array isn't sorted. I'm not sure what's wrong with my code?

A: 

It's probably because you don't have any "array values" inside your array - textual indexes are not regarded as array values but as object propertiest (arrays are "objects in disguise" in javascript). You can add as many properties to any object but array specific methods like sort take only "real" array members as their parameteres (i.e. only with numerical indexes)

var arr = new Array()
arr[0] = 1
arr[1] = 2
arr["textual_index"] = 3
alert(arr.length);

The last line alerts "2" not "3" since there are only two values with numeric indexes.

Andris
what if it were arr[textual_index] without the quotes. would that be textual indexes or "array values"?
tom
without the quotes, textual_index will be treated as a variable called textual_index and it's value is passed between [ and ], so if the variable textual_value has numeric value, then it will be treated as an array memeber otherwise as a property of an object
Andris
+3  A: 

It's not sorting because you have specified the keys that the variables within the array belong on. Sorting will only move the objects on integer-valued keys. You should see your sorting work if you create your array as follow:

var players = [new Player(), new PLayer()];

though, of course, it won't be very effective since you have neither a score on which to sort or a method of identifying them. This'll do it:

function Player(name, score) {
  this.getName = function() { return name; }
  this.getScore = function() { return score; }
  this.setScore = function(sc) { score = sc; }
}

function comparePlayers(playerA, playerB) {
  return playerA.getScore() - playerB.getScore();
}

var playerA = new Player('Paul', 10);
var playerB = new Player('Lucas', 5);
var playerC = new Player('William', 7);

var players = [playerA, playerB, playerC];

for (var i = 0; i < players.length; i++)
    alert(players[i].getName() + ' - ' + players[i].getScore());

players.sort(comparePlayers);

for (var i = 0; i < players.length; i++)
    alert(players[i].getName() + ' - ' + players[i].getScore());

Hope that helps.

icio
so there's no way to sort for associative arrays?
tom
It doesn't make sense to. By making them associative you have already sorted them yourself. What extra are you trying to achieve that is making you think you need an associative array?
icio
A: 

The main problem lies in this line:

Array(players).sort(compare);

Array(something) makes an array with something as its element.

console.log(Array(players)); //[[player1, player2]]

Use numeric indexed array instead of using object like array as in players['player1']

Run the following code (replace console.log with alert if you don't have Firebug).

function Player() {
  var score;
  //return this.score - else it returns undefined
  this.getScore = function() { return this.score; } 
  this.setScore = function(sc) { this.score = sc; }
}

function compare(playerA, playerB) {
  console.log("called " + playerA.getScore() + " " + playerB.score);
  //compare method should return 0 if equal, 1 if a > b and -1 if a < b
  return (playerA.getScore() == playerB.getScore()) ? 0 
     : ((playerA.getScore() > playerB.getScore()) ? 1 : -1);
}

var players = [];

players[0] = new Player();
players[1] = new Player();
players[2] = new Player();
players[3] = new Player();
players[0].setScore(9);
players[1].score = 14;
players[2].score = 11;
players[3].score = 10;
players.sort(compare);
console.log(players);//prints sorted array
Amarghosh