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

时间:2018-01-30 10:02:19

标签: javascript arrays string sorting 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"
  }];

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

 [{
    "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)




6 个答案:

答案 0 :(得分:3)

我有一个功能可以把这些时间变成几分钟 - 从午夜开始,就像是:

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




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

答案 1 :(得分: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) {
  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)

答案 2 :(得分:1)

正常的字符串比较适用于此,但您需要在时间字符串的开头重新排列AMPM(使用String#replace方法)。< / p>

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

使用辅助函数toMilitary,您可以将时间更改为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))

答案 5 :(得分:0)

以下是使用moment.js解析custom format的简单示例:

&#13;
&#13;
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);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
&#13;
&#13;
&#13;

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

&#13;
&#13;
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);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
&#13;
&#13;
&#13;