数据排序换行合并

此内容是我在工作对数据处理时遇到的问题,对该问题进行总结。

原数据如下

const originData = [
  { shr: '成-古力·古力', shsj: '2021-08-12 17:29:56', shyj: '', sphj: '任务发起人', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:33:06', shyj: '1', sphj: '发起人部长', spjg: '【同意】' },
  { shr: '系统管理员', shsj: '2021-08-12 17:42:58', shyj: '所有子流程结束后办理子流程节点任务', sphj: '子流程', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:33:06', shyj: '', sphj: '所有角色确认', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:37:00', shyj: '123', sphj: '业务部门部长组', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:37:00', shyj: '234', sphj: '业务部门部长组', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:33:06', shyj: '', sphj: '所有角色确认', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:33:06', shyj: '', sphj: '所有角色确认', spjg: '【同意】' },
  { shr: '凉皮', shsj: '2021-08-12 17:41:59', shyj: '567', sphj: '业务部门部长组', spjg: '【同意】' }
]

因为业务要求,我们需要把数据中的对象进行排序,所以需要对数据进行格式化。

要求顺序是['任务发起人', '发起人部长', '子流程', '业务部门部长组', '所有角色确认']

因此需要用mapfiter进行数组的格式化,下面为格式化的代码。

const getFormatData = (originData) => {
  const initOrder = ['任务发起人', '发起人部长', '子流程', '业务部门部长组', '所有角色确认']
  const result = initOrder
    .map((initOrderItem) => {
      const filterItems = originData.filter((originDataItem) => originDataItem.sphj === initOrderItem)
      const count = filterItems.length
      return filterItems.map((filterItem, index) => {
        const rowSpan = index === 0 ? count : 0
        return {
          ...filterItem,
          rowSpan
        }
      })
    })
    .flat()
  return result
}

这个代码的思路是这样的,我们对自己创建的数组进行遍历,然后用filter去过滤,当发现原数组对象中有审批环节和数组中的内容对应了,即放在一起,拆解下来是这样的。

const getFormatData = (originData) => {
  const initOrder = ['任务发起人', '发起人部长', '子流程', '业务部门部长组', '所有角色确认']
  const result = initOrder
    .map((initOrderItem) => {
      return originData.filter((originDataItem) => originDataItem.sphj === initOrderItem)
    })
    .flat()
  return result
}

这段代码即是将数据内容进行排序,因为在进行遍历时,会有两层数组嵌套,所以要使用flat将数组进行扁平化处理。

下面的换行则要对内部的数据进行处理。

const getFormatData = (originData) => {
  const initOrder = ['任务发起人', '发起人部长', '子流程', '业务部门部长组', '所有角色确认']
  const result = initOrder
    .map((initOrderItem) => {
      const filterItems = originData.filter((originDataItem) => originDataItem.sphj === initOrderItem)
      const count = filterItems.length
      return filterItems.map((filterItem, index) => {
        const rowSpan = index === 0 ? count : 0
        return {
          ...filterItem,
          rowSpan
        }
      })
    })
    .flat()
  return result
}

数据中的filterItems是相同类型的对象放在一个数组里面,因此我们先得到它的长度,在antd中,我们将rowSpan置为0,则不渲染下一行,所以这里要对数据长度进行判断,再进行一次数据的遍历,使用map的第二个可选属性,index,index指数组的索引,从0开始,在这里我们使用三元运算符判断,如果index===0,则说明它是第一个元素,将长度赋给rowSpan,多出的元素则将rowSpan置为0,不对该行进行渲染,则可以实现行的合并,由此,所有的内容都可实现行合并,该函数可以在其他地方也被调用,只需要更改数组中的数据即可,个人认为可复用性较大。