1

I have an array containing strings which look like this:

["2013-1", "2013-10", "2013-11", "2013-12", "2013-2", "2013-3", "2013-4", "2014-1", "2014-2", "2014-3"]

I'm trying to sort them like so they look like:

["2013-1", "2013-2", "2013-3", "2013-4", "2013-10", "2013-11", "2013-12", "2014-1", "2014-2", "2014-3"]

I've checked out a bunch of threads on this topic but none of the solutions have worked for me.

Using this question's answer my array didn't change at all.

var myArray =  ["2013-1", "2013-10", "2013-11", "2013-12", "2013-2", "2013-3", "2013-4", "2014-1", "2014-2", "2014-3"]
    myArray.sort(function(a,b) {
      if (isNaN(a) || isNaN(b)) {
        return a > b ? 1 : -1;
      }
      return a - b;
    });

Can't seem to find a way of doing easily doing this, any ideas of how to achieve it?

3 Answers 3

2

The problem is that it's not just numbers in a string array, there are two numbers in each string. There are many possible approchaes, you could parse the values to dates, you could parse the values to two numbers, you could split the values to a string and a number, et.c.

The approach that I suggest is to turn each string into a format that is sortable for the comparison, i.e. converting a string like "2013-1" into 2013-01. As each component in the string then has the same length, and the components are in falling importance, you can compare them as strings:

myArray.sort(function(a,b) {
  var x = a.replace(/(-\d$)/, '-0$1');
  var y = b.replace(/(-\d$)/, '-0$1');
  return (
    x > y ? 1 :
    x < y ? -1 :
    0
  );
});

var myArray = ["2013-1", "2013-10", "2013-11", "2013-12", "2013-2", "2013-3", "2013-4", "2014-1", "2014-2", "2014-3"];

myArray.sort(function(a,b) {
  var x = a.replace(/(-\d$)/, '-0$1');
  var y = b.replace(/(-\d$)/, '-0$1');
  return (
    x > y ? 1 :
    x < y ? -1 :
    0
  );
});

// output result in StackOverflow snippet
document.write(JSON.stringify(myArray));

Sign up to request clarification or add additional context in comments.

1 Comment

It would be simpler if you've used x.localeCompare(y) in return.
1

One of the ways to do so:

myArray.sort(function (a, b) {
    a = a.split("-");
    b = b.split("-");
    var montha = parseInt(a[1]),
        monthb = parseInt(b[1]);
    a = parseInt(a[0]);
    b = parseInt(b[0]);
    if (a === b) {
        return (montha - monthb);
    }
    return a - b;
});

See DEMO here.

Comments

1

Here is a functional programming approach: map strings to array of two numbers, sort that array (much easier), then map back to strings.

var input = ["2013-1", "2013-10", "2013-11", "2013-12", "2013-2", "2013-3", "2013-4", "2014-1", "2014-2", "2014-3"];
var output = input
  .map(function (val) {
    return val.split("-").map(Number);
  })
  .sort(function (a, b) {
    return a[0] - b[0] || a[1] - b[1];
  })
  .map(function (val) {
    return val.join("-");
  });

Demo: http://jsbin.com/fekiruzose/2/edit?js,console

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.