Raphael Melo De Lima
Raphael Melo De Lima

Reputation: 215

JS - Do sort in an array of strings as dates

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?

Upvotes: 2

Views: 87

Answers (5)

RobG
RobG

Reputation: 147453

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);

Upvotes: 0

Alen.Toma
Alen.Toma

Reputation: 4870

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)

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386680

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);

Upvotes: 1

nvioli
nvioli

Reputation: 4219

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);

Upvotes: 0

guest271314
guest271314

Reputation: 1

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);

Upvotes: 0

Related Questions