Tanvir Singh
Tanvir Singh

Reputation: 119

How to sort according to time in array of Object?

I have an array of object such as

[{
  time: "13:20",
  key2: "",
  key3: ""
}, {
  time: "13:40",
  key2: "",
  key3: ""
}, {
  time: "04:20",
  key2: "",
  key3: ""
}]

and I want them to sort according to time. I did some research on momentjs but I didn't found something useful.

The main problem I am facing is How to convert that time that I am getting into String format to some comparable format for sorting. Any kind of help will be appreciated.Thank you.

Upvotes: 4

Views: 80

Answers (6)

jo_va
jo_va

Reputation: 13963

If your time strings are in the HH:MM format, you can simply do a lexicographical sort with String.prototype.localeCompare():

const data = [
  { time: '13:20', key2: '', key3: '' },
  { time: '13:40', key2: '', key3: '' },
  { time: '04:20', key2: '', key3: '' },
  { time: '23:03', key2: '', key3: '' }
];

const ascending = [...data].sort((a, b) => a.time.localeCompare(b.time));
const descending = [...data].sort((a, b) => b.time.localeCompare(a.time));

console.log(JSON.stringify(ascending));
console.log(JSON.stringify(descending));

If your time strings do not follow this format, ie. may be specified as H, HH, HH:M, HH:MM..., then you can parse the string with RegExp.prototype.exec():

const data = [
  { time: '13:20', key2: '', key3: '' },
  { time: '13:40', key2: '', key3: '' },
  { time: '04:20', key2: '', key3: '' },
  { time: ' 4:25', key2: '', key3: '' },
  { time: '23:03', key2: '', key3: '' },
  { time: '14: 3', key2: '', key3: '' },
  { time: ' 2   ', key2: '', key3: '' },
];

const hourMinutes = str => /\s*(?<hh>\d*)\s*:?\s*(?<mm>\d*)\s*/.exec(str);
const toMinutes = ({ hh = 0, mm = 0 }) => (+hh) * 60 + (+mm);
const toTime = ({ time }) => toMinutes(hourMinutes(time).groups);

const ascending = [...data].sort((a, b) => toTime(a) - toTime(b));
const descending = [...data].sort((a, b) => toTime(b) - toTime(a));

console.log(JSON.stringify(ascending));
console.log(JSON.stringify(descending));

Upvotes: 2

Rajesh
Rajesh

Reputation: 24925

You can take following approach to sort it:

Logic

  • Create date object and add necessary time value you have.
  • Sort it based on these date values.

Benefit of having date based approach is that it will handle all time value cases. I have updated data to have second values as well for demonstration

var data = [{
  time: "13:20",
  key2: "",
  key3: ""
}, {
  time: "13:40",
  key2: "",
  key3: ""
}, {
  time: "04:20:10",
  key2: "",
  key3: ""
}, {
  time: "04:20:20",
  key2: "",
  key3: ""
}];

function getAddedTimeValue(time) {
  const parts = [...time.split(':'), 0, 0, 0, 0].slice(0, 4);
  const date = new Date();
  date.setHours.apply(date, parts);
  return date.getTime();
}

data.sort((a, b) => getAddedTimeValue(a.time) - getAddedTimeValue(b.time));

// For descending:
// data.sort((a, b) => getAddedTimeValue(b.time) - getAddedTimeValue(a.time));

console.log(data)

Upvotes: 2

Maheer Ali
Maheer Ali

Reputation: 36584

You make a same date for all the times. And then getTime() and compare that

let arr = [{
  time: "13:20",
  key2: "",
  key3: ""
}, {
  time: "13:40",
  key2: "",
  key3: ""
}, {
  time: "04:20",
  key2: "",
  key3: ""
}]

const toTime = (t) => new Date(`December 17, 1995 ${t}`).getTime();


arr.sort((a,b) => toTime(a.time) - toTime(b.time))

console.log(arr)

Upvotes: 3

Dacre Denny
Dacre Denny

Reputation: 30370

You could parse and sort the time field of each item in a custom callback passed to Array#sort() as shown below:

const input = [ { time : "13:20" , key2: "", key3: ""},{ time : "13:40" , key2: "", key3: ""},{ time : "04:20" , key2: "", key3: ""}];


const output = input.sort((a, b) => {
  
  const [aHours, aMinutes] = a.time.split(':');
  const [bHours, bMinutes] = b.time.split(':');
  
  if(aHours < bHours) {
    return -1;
  }
  else if(aHours > bHours) {
    return 1;
  }
  else {
    
    if(aMinutes < bMinutes) {
      return -1;
    }
    else if(aMinutes > bMinutes) {
      return 1;
    }
  }
  
  return 0; 
});

console.log(output);

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

You could get minutes of the given time and sort by this value.

const getMinutes = s => s.split(':').reduce((h, m) => h * 60 + m);

var array = [{ time: "13:20", key2: "", key3: "" }, { time: "13:40", key2: "", key3: "" }, { time: "04:20", key2: "", key3: "" }];

array.sort((a, b) => getMinutes(a.time) - getMinutes(b.time));

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Ankit Agarwal
Ankit Agarwal

Reputation: 30739

You can simply get the first numeric part that is before : and compare that for sorting and if the first part is same, then consider the second numeric part that is after :

Sort Ascending

var arr = [{
  time: "13:20",
  key2: "",
  key3: ""
}, {
  time: "13:40",
  key2: "",
  key3: ""
}, {
  time: "04:20",
  key2: "",
  key3: ""
}];

arr.sort(function(a, b) {
  var aSplit = a.time.split(':');
  var bSplit = b.time.split(':');
  return (aSplit[0] - bSplit[0] || aSplit[1] - bSplit[1]);
});
console.log(arr);

Sort Descending

var arr = [{
  time: "13:20",
  key2: "",
  key3: ""
}, {
  time: "13:40",
  key2: "",
  key3: ""
}, {
  time: "04:20",
  key2: "",
  key3: ""
}];

arr.sort(function(a, b) {
  var aSplit = a.time.split(':');
  var bSplit = b.time.split(':');
  return (bSplit[0] - aSplit[0] || bSplit[1] - aSplit[1]);
});
console.log(arr);

Upvotes: 1

Related Questions