【问题标题】:How to keep unique months in array of timestamps如何在时间戳数组中保留唯一月份
【发布时间】:2018-08-02 14:17:55
【问题描述】:

我想创建一个包含唯一月份(2015 年 8 月、2015 年 9 月等)的数组。为此,我定义了以下函数,该函数将带有时间戳的对象作为键:

export function getUniqueMonths(exps) {

  //1. get all keys from expenditures
  const days = Object.keys(exps)

  //2. convert key strings to timestamps
  const daysInt = days.map((day) => (new Date(parseInt(day))))

  //3. return only the "date portion" of the timestamp
  const datePortion = daysInt.map((day) => (new Date(day.toDateString()) ))

  //4. set each datePortion to 1st of month
  const firstOfMonth = datePortion.map((day) => new Date(day.getFullYear(), day.getMonth(), 1)  )

  //5. keep only unique firstOfMonths
  const uniqMonths = [...(new Set(firstOfMonth))]

  return uniqMonths
}

然而,这个函数给了我一个这样的数组:

[Sat Aug 01 2015 00:00:00 GMT+0300 (Eastern European Summer Time), Sat Aug 01 2015 00:00:00 GMT+0300 (Eastern European Summer Time), Tue Sep 01 2015 00:00:00 GMT+0300 (Eastern European Summer Time), Sat Aug 01 2015 00:00:00 GMT+0300 (Eastern European Summer Time), Sat Aug 01 2015 00:00:00 GMT+0300 (Eastern European Summer Time), ...]

我认为获取时间戳的日期部分(第 3 步)并将所有日期设置为月初(第 4 步)就可以了。但是我的数组中仍然有重复项。

我错过了什么?

【问题讨论】:

  • 集合使用相等来确定两个元素是否相同。日期是对象,所以相等性意味着它们必须是完全相同的日期对象,而不是引用同一时间点的两个不同的日期对象。您可以在创建 Set 之前将 Date 对象转换为字符串,然后再转换回来。
  • 太棒了,只需在第 4 步中添加 .toString() 就可以了。谢谢!

标签: javascript reactjs ecmascript-6


【解决方案1】:

我认为你可能过度设计了一些东西 :) 类似

function getUniqueMonths(exps) {
  const uniqueMonths = new Set();
  Object.keys(exps).forEach((timestamp) => {
    const date = new Date(parseInt(timestamp));  // expected to be milliseconds since 1/1/1970
    uniqueMonths.add(`${date.getFullYear()}-${date.getMonth()}`);
  });
  return uniqueMonths;
}

应该以['2017-12', '2018-0', ...] 的形式为您提供一组独特的月份(JavaScript 标准从零开始的月份)。

如果您需要 Date 对象,这些“再水合”是微不足道的。

【讨论】:

  • 这会抛出错误“未捕获的 TypeError:date.getFullYear 不是函数” - 我认为是因为 Object.keys 返回了一个字符串数组。
  • byDay: { '1440374400000': [ { id: 'caea6422-d208-4a94-a3a4-ea8b35ab8d39', createdAt: 1480510965381, updatedAt: 1480510965381, ...} ... ]
  • byDay 是 exps 对象,Object.keys(exps) 给了我 ["1440374400000", "1440720000000", "1443398400000", ...]
  • 我会将uniqueMonths.add(${date.getFullYear()}-${date.getMonth()}); 替换为uniqueMonths.add(date.toLocaleDateString("en-US", { year: 'numeric', month: 'long'}));
【解决方案2】:

两个Date 对象不是同一个对象,即使它们包含相同的时间戳。

请尝试:

//3. keep the year-month portion of the date
const yearMonths = daysInt.map(day => day.getFullYear()+"-"+day.getMonth());

然后您可以跳过4 并从那里获取唯一的年月。例如,这些将在 2015 年 8 月以 "2015-7" 的形式返回。

【讨论】:

    猜你喜欢
    • 2020-01-18
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    相关资源
    最近更新 更多