簡體   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