2

I have the following array:

let datas = ["nov/2018", "set/2018", "jan/2019", "dez/2018", "out/2018"]

when I execute

datas.sort()

he orders by alphabetical order, however, I must order first by the year and then by alphabetical order.

["dez/2018", "jan/2019", "nov/2018", "out/2018", "set/2018"]

Testing today I arrived at the following line of code:

var datas = ["mar", "abr", "jan", "dez", "set", "mai", "jun", "out", "jul"];
var datas_corretas = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"];
var result = [];

datas_corretas.forEach(function ordenar(element, index){
  var mes = datas.filter(function(valor){
  return valor == datas_corretas[index];
});
  result.push(mes[0]);
  for(element of result){
    if (element === undefined || element === null){
      result.pop(element);
    }
  }
});
console.log(result);

That way I can sort the data, but the problem is when I use it with the year

var datas = ["mar/2018", "abr/2018", "jan/2019", "dez/2018", "set/2018", "mai/2018", "jun/2018", "out/2018", "jul/2018"];

Does anyone have any idea how I can resolve this?

3
  • 1
    What do you mean by "and then by alphabetical order"? Commented Feb 15, 2019 at 19:16
  • So for a given input, what exactly do you want the output to be? Are you actually trying to put these in date order? If so, then you'll need to sort by first comparing the year part, and then the month part. Commented Feb 15, 2019 at 19:18
  • 1
    please add the wanted result as well. Commented Feb 15, 2019 at 19:21

5 Answers 5

1

You could split the dates and sort by year first, and then by the index of the month.

var months = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"],
    datas = ["nov/2018", "set/2018", "jan/2019", "dez/2018", "out/2018"];

datas.sort((a, b) => {
    var aa = a.split('/'),
        bb = b.split('/');
    return aa[1] - bb[1] || months.indexOf(aa[0]) - months.indexOf(bb[0]);
});

console.log(datas);

For a faster access, you could store the months as object.

var months = { jan: 1, fev: 2, mar: 3, abr: 4, mai: 5, jun: 6, jul:7, ago: 8, set: 9, out: 10, nov: 11, dez: 12 },
    datas = ["nov/2018", "set/2018", "jan/2019", "dez/2018", "out/2018"];

datas.sort((a, b) => {
    var aa = a.split('/'),
        bb = b.split('/');
    return aa[1] - bb[1] || months[aa[0]] - months[bb[0]];
});

console.log(datas);

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

Comments

0

however, I must order first by the year and then by alphabetical order.

["dez/2018", "jan/2019", "nov/2018", "out/2018", "set/2018"]

To achieve the expected result you can use .sort() twice, .split() at "/", .pop() and .shift()

datas.sort((a, b) => a.split("/").pop() < b.split("/").pop() ? -1 : 0)
.sort((a, b) => a.split("/").shift() < b.split("/").shift() ? -1 : 0);

Comments

0

TIL you can pass a custom comparator to javascript's sort function. We can use this to write our own sorting logic by first comparing the years, then the months:

let datas = ["nov/2018", "set/2018", "jan/2019", "dez/2018", "out/2018"]
const orderedMonths = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"];

datas.sort((a,b) => {
  var [montha,yeara] = a.split('/');
  var [monthb,yearb] = b.split('/');
  
  if (yeara > yearb) return 1;
  if (yearb > yeara) return -1;
  if (orderedMonths.indexOf(montha) > orderedMonths.indexOf(monthb)) return 1;
  if (orderedMonths.indexOf(monthb) > orderedMonths.indexOf(montha)) return -1;
  return 0;
});

console.log(datas);

Comments

0

its very easy when converting the value to numbers and index.

Here se my example below.

var datas_corretas = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"];

var datas = ["mar/2018", "abr/2018", "jan/2019", "dez/2018", "set/2018", "mai/2018", "jun/2018", "out/2018", "jul/2018"];

var result = datas.sort(function(a, b){
// index of the month
var aMonth = datas_corretas.indexOf(a.split("/")[0]);
// convert the year to number
var aYear = parseInt(a.split("/")[1]);

var bMonth = datas_corretas.indexOf(b.split("/")[0])
var bYear = parseInt(b.split("/")[1])

return aYear - bYear || aMonth - bMonth;
});

console.log(result)

Comments

0

I must order first by the year and then by alphabetical order.

Answers seem to all sort the month chronologically, so here's how to sort them alphabetically. Split in to month and year, then firstly compare years then compare months using localeCompare.

let datas = ["nov/2018", "set/2018", "jan/2019", "dez/2018", "out/2018"]

datas.sort((a, b) => {
  let [amon, ayr] = a.split('/');
  let [bmon, byr] = b.split('/');
  return (ayr - byr) || amon.localeCompare(bmon);
});

console.log(datas);

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.