anon
anon

Reputation:

What is the difference between the following cases when using Array.sort() in javascript?

CASE 1:

let items = [
  { name: "Edward", value: 21 },
  { name: "Shane", value: 37 },
  { name: "Daniel", value: 45 },
  { name: "Daniel", value: -12 },
  { name: "Magnetic", value: 13 },
  { name: "Magnetic", value: 37 },
];

items.sort(function (a, b) {
  if (a.name<b.name) {
    return -1;
  }
  if (a.name>b.name) {
    return 1;
  }
  // names must be equal
  return 0;
});

console.log(items);

CASE 2:

let items = [
  { name: "Edward", value: 21 },
  { name: "Shane", value: 37 },
  { name: "Daniel", value: 45 },
  { name: "Daniel", value: -12 },
  { name: "Magnetic", value: 13 },
  { name: "Magnetic", value: 37 },
];

items.sort(function (a, b) {
  if (a.name<b.name) {
    return -1;
  }
  if (a.name>b.name) {
    return 1;
  }
  // no case for equal names
});

console.log(items);

CASE 3:

items.sort(function (a, b) {
  return a.name < b.name ? -1 : 1;
});

All three return the following

[
  { name: 'Daniel', value: 45 },
  { name: 'Daniel', value: -12 },
  { name: 'Edward', value: 21 },
  { name: 'Magnetic', value: 13 },
  { name: 'Magnetic', value: 37 },
  { name: 'Shane', value: 37 }
]

All the above mentioned snippets return the same result, but there's definitely some example where all these return different results (Which I don't know). I wanted to know what happens when there's no return condition for the names being equal.

UPDATE: I've added a case 3 to the original question, actually case 1 and case 2 behave similarly because case 2 returns undefined when names are equal. But in case 3 where I use ternary operator it doesn't return undefined but still the answer remains the same. HOW?

Upvotes: 3

Views: 114

Answers (2)

epascarello
epascarello

Reputation: 207527

The main issue with your code is you are comparing Objects which makes no sense. So you should do sorting on a property in the object. Look at what the tests do.

var a = { foo: 1 };
var b = { foo: 2 };

console.log("a > b", a > b);
console.log("a > b", a < b);
console.log("a == b", a == b);

So in your sort you are literally have the same result in each check. It makes no sense. You need to look at the data in the object. You should be checking for 3 states 1) SAME, 2) Greater, and 3) Less Than.

When you do not return correct values for each state, you may run into browser sorting items differently each time. In your case you are not returning anything when it is equal and that will be seen as undefined and that us a falsely value so should probably be 0 which is equal. When you are just returning 1 and -1, you are making the browser do a lot more work since it is getting different values every time is makes a comparison. That will cause sort order to differ and can make it take extra long since it makes extra calculations.

let items = [
  { name: "Car", value: 100 },
  { name: "Apple", value: 21 },
  { name: "Car", value: 13 },
  { name: "Far", value: 37 },
  { name: "Apple", value: 10 },
  { name: "Bar", value: 45 }
];


items.sort( function (a, b) {

  // if names are equal lets sort on value
  if (a.name === b.name) {
    if (a.value === b.value) {
      return 0;
    } else if (a.value > b.value) {
      return 1;
    } else {
      return -1;
    }
  }
  else if (a.name > b.name) {
    return 1;
  }
  else {
    return -1;
  }
});

console.log(items);

Code cleaned up

let items = [
  { name: "Car", value: 100 },
  { name: "Apple", value: 21 },
  { name: "Car", value: 13 },
  { name: "Far", value: 37 },
  { name: "Apple", value: 10 },
  { name: "Bar", value: 45 }
];

items.sort( function (a, b) {

  // if names are equal lets sort on value
  if (a.name === b.name) {
    if (a.value === b.value) {
      return 0;
    } else {
      return (a.value > b.value) ? 1 : -1;
    }
  } else {
    return a.name.localeCompare(b.name);
  }
});

console.log(items);

Upvotes: 1

Shadab
Shadab

Reputation: 1347

If you don't specify a return for a function it returns undefined

function f() {
  // no return specified
}

let x = f(); // undefined

Now undefined is a falsy value, i.e. it can be coerced to false or 0. So although you're not explicitly returning 0, you're returning undefined which can sometimes work like 0

Another way to write this would be

items.sort(function (a, b) {
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }
  
  // return "undefined" if it gets to this line
});

Upvotes: 0

Related Questions