js实现行转列

47 阅读1分钟

只有一个分组字段

import { describe, it } from 'vitest'

interface PersonScoe {
  name: string
  scoe: number
  subject: string
}

type RowData = { name: string } | Record<string, number>
describe('行转列测试', () => {
  it('初级', () => {
    const arr: PersonScoe[] = [
      { name: '张三', subject: '语文', scoe: 90 },
      { name: '张三', subject: '数学', scoe: 100 },
      { name: '张三', subject: '英语', scoe: 120 },
      { name: '李四', subject: '语文', scoe: 80 },
      { name: '李四', subject: '数学', scoe: 89 },
      { name: '李四', subject: '英语', scoe: 75 }
    ]
    const config = {
      // 分组字段
      groupField: 'name',
      // 数据字段
      dataField: 'scoe',
      // 行转列字段
      rowMappingColumnField: 'subject',
      // 行字段与列名映射
      valueFieldMappingArr: [
        { field: 'sub1', title: '语文' },
        { field: 'sub2', title: '数学' },
        { field: 'sub3', title: '英语' }
      ]
    }

    const retArr = arr
      .reduce<Map<string | number, RowData>>((prev, cur) => {
        const groupFieldVal = cur[config.groupField]
        const rowData: RowData = prev.get(groupFieldVal) ?? {}
        prev.set(groupFieldVal, rowData)

        rowData[config.groupField] = cur[config.groupField]

        const columnValue = cur[config.rowMappingColumnField]
        const valueFieldMappingArr = config.valueFieldMappingArr
        const valueFieldMapping = valueFieldMappingArr.find((item) => item.title === columnValue)

        if (valueFieldMapping) {
          const data = cur[config.dataField]
          rowData[valueFieldMapping.field] = data
        }
        return prev
      }, new Map<string | number, RowData>())
      .values()
    console.log('retArr', retArr)
  })
})

image.png