0

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

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

我的计划是对其进行格式化,使其与 d3 一起绘制为条形图。条形图有一个选择器,您可以将数据分组为weekdaymonthyear。我决定创建一个名为groupBylodash 的函数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可以做到这一点,或者是否有任何解决方法。非常感谢您的回复。

4

1 回答 1

0

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

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

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>

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

于 2021-07-24T09:37:08.943 回答