繁体   English   中英

根据时间字符串值对对象数组进行排序?

[英]Sort an array of objects based on times string values?

我有一系列对象

var data =[
  {
    "avail": "3 Bookings Available" 
    "time": "05:00 PM to 06:00 PM",
    "date": "2018-01-30"
  },
  {
    "avail": "3 Bookings Available",
    "time": "09:00 AM to 10:00 AM",
    "date": "2018-01-30"
  },
  {
    "avail": "3 Bookings Available",
    "time": "04:00 PM to 05:00 PM",
    "date": "2018-01-30"
  },
  {
    "avail": "3 Bookings Available",
    "time": "03:00 PM to 04:00 PM",
    "date": "2018-01-30"
  }];

我想按时间字符串值对数据进行排序,以便所需的输出如下所示:

 [{
    "avail": "3 Bookings Available" 
    "time": "09:00 AM to 10:00 AM",
    "date": "2018-01-30"
  },
  {
    "avail": "3 Bookings Available",
    "time": "03:00 PM to 04:00 PM",
    "date": "2018-01-30"
  },
  {
    "avail": "3 Bookings Available",
    "time": "04:00 PM to 05:00 PM",
    "date": "2018-01-30"
  },
  {
    "avail": "3 Bookings Available",
    "time": "05:00 PM to 06:00 PM",
    "date": "2018-01-30"
  }]

我已经使用了String #localeCompare的sort函数,但是仍然无法获得所需的输出

data.sort(function(a,b){
  return a.time.localeCompare(b.time);
});
console.log(data);

即使我使用String#slice()方法,通过它我也可以使用'1970/01/01'作为任意日期来生成有效的日期字符串,但我仍在获取所需的信息,任何人都可以通过这种方式给我可以通过这种方式获得输出预先感谢。

data.sort(function(a, b) {
  return Date.parse('1970/01/01 ' + a.time.slice(0, -2) + ' ' + a.time.slice(-2)) - Date.parse('1970/01/01 ' + b.time.slice(0, -2) + ' ' + b.time.slice(-2))
});

例:

 var data = [{ "avail": "3 Bookings Available", "time": "05:00 PM to 06:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "09:00 AM to 10:00 AM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "04:00 PM to 05:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "03:00 PM to 04:00 PM", "date": "2018-01-30" } ]; data.sort(function(a, b) { return Date.parse('1970/01/01 ' + a.time.slice(0, -2) + ' ' + a.time.slice(-2)) - Date.parse('1970/01/01 ' + b.time.slice(0, -2) + ' ' + b.time.slice(-2)) }); console.log(data) 

从午夜起,我将有一个功能可以将这些时间转换为分钟,大致类似于:

function parseTime(time) {
  var parts = time.match(/^(\d{2}):(\d{2}) (AM|PM)/i);
  if (!parts) {
    return NaN;
  }
  var adjust = parts[3].toUpperCase() == "PM" ? 12 : 0;
  return (parseInt(parts[1], 10) + adjust) * 60 + parseInt(parts[2], 10);
}

然后排序很简单:

data.sort(function(a, b) {
  return parseTime(a.time) - parseTime(b.time);
});

例:

 var data =[ { "avail": "3 Bookings Available", "time": "05:00 PM to 06:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "09:00 AM to 10:00 AM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "04:00 PM to 05:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "03:00 PM to 04:00 PM", "date": "2018-01-30" }]; function parseTime(time) { var parts = time.match(/^(\\d{2}):(\\d{2}) (AM|PM)/i); if (!parts) { return NaN; } var adjust = parts[3].toUpperCase() == "PM" ? 12 : 0; return (parseInt(parts[1], 10) + adjust) * 60 + parseInt(parts[2], 10); } data.sort(function(a, b) { return parseTime(a.time) - parseTime(b.time); }); console.log(data); 
 .as-console-wrapper { max-height: 100% !important; } 

经典的分而治之(例如,将问题分解成较小的部分)。

这有效(添加缺失的逗号后):

 var data = [{ "avail": "3 Bookings Available", "time": "05:00 PM to 06:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "09:00 AM to 10:00 AM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "04:00 PM to 05:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "03:00 PM to 04:00 PM", "date": "2018-01-30" } ]; data.sort(function(a, b) { const [afrom, ato]=a.time.split(" to "); const [bfrom, bto]=b.time.split(" to "); return Date.parse(a.date + " " + afrom) - Date.parse(b.date + " "+ bfrom); }); console.log(data) 

正常的字符串比较可以解决此问题,但是您需要在时间字符串的开头重新排列AMPM (为此使用String#replace方法)。

 var data = [{ "avail": "3 Bookings Available", "time": "05:00 PM to 06:00 PM", "date": "2018-01-30"}, { "avail": "3 Bookings Available", "time": "09:00 AM to 10:00 AM", "date": "2018-01-30"}, { "avail": "3 Bookings Available", "time": "04:00 PM to 05:00 PM", "date": "2018-01-30"}, { "avail": "3 Bookings Available", "time": "03:00 PM to 04:00 PM", "date": "2018-01-30"}]; data.sort(function(a, b) { // compare the date string return a.date.localeCompare(b.date) || // in case they are equal then compare time string // after converting the format timeFormat(a).localeCompare(timeFormat(b)) }); // function for formating the time string function timeFormat(o) { // reposition the AM or PM at the beginning of time // for string comparison return o.time.replace(/(\\d{2}:\\d{2}\\s)(AM|PM)/g, '$2$1'); } console.log(data); 

您可以合并日期和时间,并创建一个日期对象,您可以获取自1970年以来的时间(以毫秒为单位),比较这些数字并相应地对数组进行排序。

使用辅助功能到军事,您可以将时间更改为0到2359之间的数字。然后将原始数据映射到军事时间和索引。 然后整理一下军事时间。 最后,使用排序集的索引来减少结果,以从原始数据中选择项目。

以下代码不会更改任何原始数据。

  const data =[ { "avail": "3 Bookings Available", "time": "05:00 PM to 06:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "09:00 AM to 10:00 AM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "04:00 PM to 05:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "03:00 PM to 04:00 PM", "date": "2018-01-30" } ]; const toMilitary = timeString => { const time = timeString.slice(0,8); const amPm = time.slice(-2).toLowerCase(); const timeNumber = parseInt(time.replace(/[^0-9]/g,""),10); return (amPm==="pm")?timeNumber+1200:timeNumber; }; const sortedData = data .map((d,index)=>[ toMilitary(d.time), index ]) .sort((a,b)=>a[0]-b[0]) .reduce( (all,[_,index])=> all.concat([data[index]]), [] ); console.log(JSON.stringify(sortedData,undefined,2)) 

我喜欢mplungjan方式,它包含日期。 排序时它将多次调用解析日期和时间函数,因此我已经实现了它,而不是以前的实现。 首先计算所有对象的完整日期和时间,并与索引配对,然后进行排序,然后使用排序结果的索引从数据中选择项目:

 const data =[ { "avail": "3 Bookings Available", "time": "05:00 PM to 06:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "09:00 AM to 10:00 AM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "04:00 PM to 05:00 PM", "date": "2018-01-30" }, { "avail": "3 Bookings Available", "time": "03:00 PM to 04:00 PM", "date": "2018-01-30" } ]; const fullDate = item => { const [from, to]=item.time.split(" to "); return Date.parse(item.date + " " + from); }; const sortedData = data .map((d,index)=>[ fullDate(d),index ]) .sort((a,b)=>a[0]-b[0]) .reduce( (all,[_,index])=> all.concat([data[index]]), [] ); console.log(JSON.stringify(sortedData,undefined,2)) 

这是一个使用moment.js解析自定义格式的简单示例:

 var data = [ { "time": "05:00 PM to 06:00 PM", "date": "2018-01-30" }, { "time": "09:00 AM to 10:00 AM", "date": "2018-01-30" }, { "time": "04:00 PM to 05:00 PM", "date": "2018-01-30" }, { "time": "03:00 PM to 04:00 PM", "date": "2018-01-30" } ]; data.sort(function(a, b) { let format = "YYYY-MM-DD hh:mm A"; let ma = moment(a.date + " " + a.time, [format]) let mb = moment(b.date + " " + b.time, [format]) return ma.diff(mb); }); console.log(data); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script> 

这是另一个示例,其中还包括排序中的结束时间(如果两个开始日期/时间相等):

 var data = [ { "time": "09:00 PM to 06:00 PM", "date": "2018-01-30" }, { "time": "09:00 PM to 10:00 AM", "date": "2018-01-30" }, { "time": "09:00 PM to 05:00 PM", "date": "2018-01-30" }, { "time": "09:00 PM to 04:00 PM", "date": "2018-01-30" } ]; data.sort(function(a, b) { let format = "YYYY-MM-DD hh:mm A"; let ma = moment(a.date + " " + a.time, [format]) let mb = moment(b.date + " " + b.time, [format]) let diff = ma.diff(mb); if(diff === 0) { ma = moment(a.date + " " + a.time.substring(12), [format]) mb = moment(b.date + " " + b.time.substring(12), [format]) diff = ma.diff(mb); } return diff; }); console.log(data); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM