0

I have the following code:

function compare(a,b) {
    if (a.title < b.title)
        return -1;
    if (a.title > b.title)
        return 1;
    return 0;
}
.
.
setsArr.sort(compare);

This should sort an array objects alphabetically based on their title property. When there is a space in the title, however, that title will come before the other titles with no space in them unless those titles start with a number or a special character.

An example of the ordered list could be:

  • 3xd

  • My Little Pony

  • Aladdin

  • Batman

I would like 'My Little Pony' to come last. How could I accomplish this?

Mardymar
  • 419
  • 3
  • 14
  • Case insensitive or sensitive? – Grim Nov 15 '15 at 16:59
  • This is may help u: http://stackoverflow.com/questions/1179366/is-there-a-javascript-strcmp – Shondeslitch Nov 15 '15 at 17:06
  • 1
    This is unclear. Do you want **all** entries that have spaces to be at the end, after all that don't? Or following based on, I don't know, the first letter -- so "My Little Pony" would be after "Myanmar" but before "Nygaard"? – T.J. Crowder Nov 15 '15 at 17:13
  • You're saying items with a space should come before those without a space, but then you say *"unless those titles start with a number or a special character."*. So what does that mean? If they start with a number or special character and have a space, should they all be grouped at the beginning? Or should they be sorted with the no space ones alphabetically? Or should they be sorted with their spaces removed? –  Nov 15 '15 at 17:18
  • And does the *"those titles"* ones refer to the ones with the space, or without. –  Nov 15 '15 at 17:21
  • The example I gave is how the code is currently sorting the list. This is clearly not a good order for the items. – Mardymar Nov 16 '15 at 17:17

2 Answers2

0

This is really just a special case of the general: How do I sort by two criteria? In this case, the first criterion is whether one or both of the entries has a space:

function compare(a,b) {
  var aHasSpace = a.indexOf(" ") != -1;
  var bHasSpace = b.indexOf(" ") != -1;

  if (aHasSpace != bHasSpace) {
    return aHasSpace ? 1 : -1;
  }
  return a.localeCompare(b);
}

Note also the use of localeCompare for simplicity.

Live Example:

var titles = ["3xd", "My Little Pony", "Aladdin", "Another One With A Space", "Batman"];

function compare(a,b) {
  var aHasSpace = a.indexOf(" ") != -1;
  var bHasSpace = b.indexOf(" ") != -1;
  
  if (aHasSpace != bHasSpace) {
    return aHasSpace ? 1 : -1;
  }
  return a.localeCompare(b);
}

titles.sort(compare);
document.body.innerHTML = JSON.stringify(titles);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Shouldn't "Batman" come after "Another One With A Space"? Or am I misunderstanding the criteria? –  Nov 15 '15 at 17:11
  • @squint: I thought the criterion was to put all containing spaces at the end, sorted. I may be the one misunderstanding. The example in the question is pretty unclear. – T.J. Crowder Nov 15 '15 at 17:12
  • I think maybe we're both wrong, Seems like he's saying 1) Items that start with special character or number, 2) Items that contain a space 3) All the rest sorted alphabetically. Although the *"unless"* in his description could be interpreted a couple different ways. –  Nov 15 '15 at 17:15
0
var setsArr = [ '3xd', 'My Little Pony', 'Aladdin', 'Batman' ];

function compare(a,b) {
    return a.replace(/ /g, '').localeCompare(b.replace(/ /g, ''));
}

setsArr.sort(compare);

return ["3xd", "Aladdin", "Batman", "My Little Pony"]

David Zorychta
  • 13,039
  • 6
  • 45
  • 81
  • This worked. I had to make a small edit, since it was an array of objects. So i made it `return a.title.replace(/ /g, '').localeCompare(b.title.replace(/ /g, ''));` – Mardymar Nov 15 '15 at 17:10
  • I think you'll find that that gets tricked by, say, `['3xd', 'BatmanReturns', 'Batman 2k', 'Batman']`. (@Mardymar, FYI) – T.J. Crowder Nov 15 '15 at 17:10