在JavaScript中将日期和时间作为字符串的对象数组排序

axkjgtzd  于 2023-04-28  发布在  Java
关注(0)|答案(4)|浏览(131)

我正在创建一个对象数组,它看起来像

let obj = {
    date: String,
    time: String,
    text: String,
  }

日期格式是“MM-DD-YYYY”,时间格式是“HH:MM:SS”,我从API中获取此格式,无法更改格式,我需要按照日期和时间的升序对数组进行排序,即对于相同的日期,时间的升序。我试过使用JS Date和Moment,但没有成功。使用Date(a.date) - Date(b.date)只按日期排序是可行的,但如果我尝试将时间也包括在内,它就不行了,甚至连(Date(a.date) - Date(b.date)) || (a.time.localeCompare(b.time))都不行
如何在JavaScript(NodeJS)中实现这一点?

qyzbxkaa

qyzbxkaa1#

您可以将日期和时间字符串转换为JavaScript Date对象,然后使用sort()方法:

arr.sort(function(a, b) {
  // Convert date strings to Date objects
  let dateA = new Date(a.date + " " + a.time);
  let dateB = new Date(b.date + " " + b.time);

  // Compare dates and times
  if (dateA < dateB) {
    return -1;
  } else if (dateA > dateB) {
    return 1;
  } else {
    return 0;
  }
});
wqsoz72f

wqsoz72f2#

我可以通过下面的sort函数来解决这个问题:

arr.sort((a, b) => {
  // Convert date strings to Date objects
  const dateA = new Date(a.date);
  const dateB = new Date(b.date);

  // Compare dates
  if (dateA < dateB) return -1;
  if (dateA > dateB) return 1;

  // If dates are equal, compare times
  const timeA = a.time.split(':');
  const timeB = b.time.split(':');

  for (let i = 0; i < 3; i++) {
    const numberA = parseInt(timeA[i]);
    const numberB = parseInt(timeB[i]);

    if (numberA < numberB) return -1;
    if (numberA > numberB) return 1;
  }

  return 0;
});

向ChatGPT致敬!

vshtjzan

vshtjzan3#

使用下面的排序逻辑,您可以将日期和时间放在一起,这样就不需要在每次将每个项与另一项进行比较时重新解析每个项。

const main = () => {
  const sortedData = data.sort((a, b) =>
      retrieveByDateAndTime(a) - retrieveByDateAndTime(b)
    || a.text.localeCompare(b.text));

  hashLookup.clear(); // Clear the map (optional)

  console.log(sortedData); // Display the sorted data
}

// Optimize sorting speed by hashing
const hashLookup = new Map();
const parseDateAndTime = (date, time) => {
  const [_month, _date, _year] = date.split('-').map(v => parseInt(v, 10));
  const [_hour, _min, _sec] = time.split(':').map(v => parseInt(v, 10));
  return new Date(_year, _month - 1, _date, _hour, _min, _sec);
};
const retrieveByDateAndTime = ({ date, time }) => {
  const hash = generateHashCode(date + 'T' + time);
  let storedDate = hashLookup.get(hash);
  if (!storedDate) {
    storedDate = parseDateAndTime(date, time);
    hashLookup.set(hash, storedDate);
  }
  return storedDate;
};

// Credit: https://stackoverflow.com/a/8831937/1762224
const generateHashCode = (str) => {
  let hash = 0;
  for (let i = 0, len = str.length; i < len; i++) {
    let chr = str.charCodeAt(i);
    hash = (hash << 5) - hash + chr;
    hash |= 0;
  }
  return hash;
}

// Generated with https://www.mockaroo.com
const data = [
  { "date": "06-29-2022", "time": "14:27:00", "text": "Mustang"     },
  { "date": "11-10-2022", "time": "20:42:00", "text": "Firebird"    },
  { "date": "06-29-2022", "time": "00:22:00", "text": "Mustang"     },
  { "date": "11-10-2022", "time": "20:00:00", "text": "E-Series"    },
  { "date": "06-29-2022", "time": "10:58:00", "text": "E-Series"    },
  { "date": "05-18-2022", "time": "02:59:00", "text": "IS"          },
  { "date": "01-14-2023", "time": "09:15:00", "text": "Truck"       },
  { "date": "01-13-2023", "time": "00:17:00", "text": "CLS-Class"   },
  { "date": "11-10-2022", "time": "18:10:00", "text": "Oasis"       },
  { "date": "09-14-2022", "time": "04:15:00", "text": "Monte Carlo" }
];

main(); // Now, call main
.as-console-wrapper { top: 0; max-height: 100% !important; }
b4lqfgs4

b4lqfgs44#

对于每个对象,从["date"][time]字符串创建一个格式正确的日期-时间字符串。

const formattedDate = obj.date.split("-").join("/");
// "01-01-1970" to "01/01/1970"
const dateTime = formattedDate + " " obj.time;
// "01/01/1970 00:00:00"

然后使用Date()构造函数将新字符串转换为Date对象,然后将.parse()转换为时间戳编号。

obj.stamp = Date.parse(new Date("01/01/1970 00:00:00"));
// 28800000

详细信息在示例中注解

// Note the value of each ["text"] key implies object's true position.
const dataLog = [
  { date: "04-20-2001", time: "20:20:20", text: "5" },
  { date: "12-31-1999", time: "23:59:59", text: "3" },
  { date: "08-16-1998", time: "00:01:36", text: "1" },
  { date: "08-16-1998", time: "01:40:19", text: "2" },
  { date: "04-27-2023", time: "08:53:00", text: "6" },
  { date: "04-20-2001", time: "10:00:01", text: "4" }
];
// Utility function that formats and displays data to the console.
const log = data => console.log(JSON.stringify(data));

/**
 * Returns a given array of Objects in ascending order of each object
 * by the combined values of ["date"] and ["time"] as a new number value
 * under the added key ["stamp"].
 * @param {array<Object>} data - An array of Objects (see Object Example). 
 *                        Object Example 
 *                        { date: "01-01-1970", 
 *                          time: "00:00:00",
 *                          text: "0" }
 * @param {boolean}       clean - true: array is returned without timestamps. 
 *                                false: array is returned with timestamps.
 * @default {boolean}     clean - true
 * @returns {array<Object>} - See description above.
 */
const sortLog = (data, clean = true) => {
  let stamped = data.map(obj => {
    // Format ["date"] values from MM-DD-YYYY to MM/DD/YYYY
    const d = obj.date.split("-").join("/");
    /* Add ["stamp"] property. Value is the newly formatted
     * ["date"] value and ["time"] value parsed into a timestamp
     * (a number of msec since 01/01/1970).
     */
    obj.stamp = Date.parse(new Date(d+" "+obj.time));
    return obj;
  });
  // Sort each object in ascending order by ["stamp"] value.
  stamped.sort((a, b) => a.stamp - b.stamp);
  // Return array of Objects with timestamps if -clean is passed as false.
  return clean ? stamped.map(obj => {
    delete obj.stamp;
    return obj;
  }) : stamped;
}

// Without timestamps
log(sortLog(dataLog));
// With timestamps
log(sortLog(dataLog, false));

相关问题