Dayjs:按天分组数据,同时仍保持格式

Dayjs: group data by each day while still keeping the format

我有来自 API 的以下数据结构,它以 Data 的数组形式出现,每个 Data 元素间隔 1 小时。

interface Data {
  time_bucket: string // ISO8601 string
  aggregated_value: number // 0 and up
}

我的计划是对其进行格式化,以便与 d​​3 一起绘制为条形图。条形图有一个选择器,您可以将数据分组为 weekdaymonthyear。我决定创建一个名为 groupBy 的函数,它的工作方式与 lodash 的 groupBy 非常相似。它将数据分组到您想要的指定组。这是函数

export function groupBy<T, K extends keyof any> (list: T[], criteria: (item: T) => K): Record<K, T[]> {
  return list.reduce<Record<K, T[]>>((prev, curr) => {
    const group = criteria(curr)
    // eslint-disable-next-line
    if (!prev[group]) {
      prev[group] = []
    }
    prev[group].push(curr)
    return prev
    // eslint-disable-next-line
  }, {} as Record<K, T[]>)
}

问题是图的x尺度是以YYYY-MM-DD格式构造的。我想将数据分组到每一天 ,同时将日期格式保持为 YYYY-MM-DD。我现在从 运行 中得到的功能在片段中看起来像这样。

const data = [
  {
    time_bucket: '2021-06-01T16:00:00.000Z',
    aggregated_value: 20
  },
  {
    time_bucket: '2021-06-01T18:00:00.000Z',
    aggregated_value: 20
  },
  {
    time_bucket: '2021-06-02T16:00:00.000Z',
    aggregated_value: 40
  },
  {
    time_bucket: '2021-06-02T20:00:00.000Z',
    aggregated_value: 40
  },
  {
    time_bucket: '2021-06-03T05:00:00.000Z',
    aggregated_value: 60
  }
]

function groupBy(list, criteria) {
  return list.reduce((prev, curr) => {
    const group = criteria(curr)
    if (!prev[group]) {
      prev[group] = []
    }
    prev[group].push(curr)
    return prev
  }, {})
}

console.log(groupBy(data, (item) => dayjs.utc(item.time_bucket).get('date')))
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://unpkg.com/dayjs@1.8.21/plugin/utc.js"></script>
<script>dayjs.extend(window.dayjs_plugin_utc)</script>

你可以看到输出是这样的:

{
  "1": [
    {
      "time_bucket": "2021-06-01T16:00:00.000Z",
      "aggregated_value": 20
    },
    {
      "time_bucket": "2021-06-01T18:00:00.000Z",
      "aggregated_value": 20
    }
  ],
  "2": [
    {
      "time_bucket": "2021-06-02T16:00:00.000Z",
      "aggregated_value": 40
    },
    {
      "time_bucket": "2021-06-02T20:00:00.000Z",
      "aggregated_value": 40
    }
  ],
  "3": [
    {
      "time_bucket": "2021-06-03T05:00:00.000Z",
      "aggregated_value": 60
    }
  ]
}

这就是我想要的

{
  "2021-06-01": [
    {
      "time_bucket": "2021-06-01T16:00:00.000Z",
      "aggregated_value": 20
    },
    {
      "time_bucket": "2021-06-01T18:00:00.000Z",
      "aggregated_value": 20
    }
  ],
  "2021-06-02": [
    {
      "time_bucket": "2021-06-02T16:00:00.000Z",
      "aggregated_value": 40
    },
    {
      "time_bucket": "2021-06-02T20:00:00.000Z",
      "aggregated_value": 40
    }
  ],
  "2021-06-03": [
    {
      "time_bucket": "2021-06-03T05:00:00.000Z",
      "aggregated_value": 60
    }
  ]
}

我想从函数中得到的是能够将数据分组到指定范围内,同时为我保留 YYYY-MM-DD 格式 的日期格式仍然将其映射到我生成的 d3 x 比例。 dayjs 中是否有任何函数可以执行此操作或是否有任何解决方法。非常感谢您的回复。

经过一段时间的研究。我决定将任何日期四舍五入到每个时间范围的开始。

我会在示例中像这样使用它。

const data = [
  {
    time_bucket: '2021-06-01T16:00:00.000Z',
    aggregated_value: 20
  },
  {
    time_bucket: '2021-06-01T18:00:00.000Z',
    aggregated_value: 20
  },
  {
    time_bucket: '2021-06-02T16:00:00.000Z',
    aggregated_value: 40
  },
  {
    time_bucket: '2021-06-02T20:00:00.000Z',
    aggregated_value: 40
  },
  {
    time_bucket: '2021-06-03T05:00:00.000Z',
    aggregated_value: 60
  }
]

function groupBy(list, criteria) {
  return list.reduce((prev, curr) => {
    const group = criteria(curr)
    if (!prev[group]) {
      prev[group] = []
    }
    prev[group].push(curr)
    return prev
  }, {})
}

console.log(groupBy(data, (item) => dayjs.utc(item.time_bucket).startOf('day').format('YYYY-MM-DD')))
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://unpkg.com/dayjs@1.8.21/plugin/utc.js"></script>
<script>dayjs.extend(window.dayjs_plugin_utc)</script>

这样我就可以使用从 startOf() 公开的 .format() 将数据分组到每个时间范围内。