如何在 Javascript 中合并数组和按键分组?

How can I merge an array and group by key in Javascript?

我在 reactjs 中有多个数组。

{last_name: 'User1', status: 'BRONZE', type: 'Maintenance', due_date: '2022-06-04 00:00:00'}
{last_name: 'User1', status: 'BRONZE', type: 'Contrôle technique', due_date: '2022-06-18 00:00:00'}
{last_name: 'User2', status: 'BRONZE', type: 'Unknow', due_date: null}

我想按用户 last_name 合并数组以获得如下结果:

{last_name: 'User1', status1: 'BRONZE', type: 'Maintenance1', due_date1: '2022-06-04 00:00:00', status2: 'BRONZE', type2: 'Contrôle technique', due_date: '2022-06-18 00:00:00'}
{last_name: 'User2', status: 'BRONZE', type: 'Unknow', due_date: null}

在我的示例中,我将数组 1 和 2 合并为 1 个数组“分组依据”last_name,这里是 User1,但我也需要保留第二个数组的值。

您的问题缺少一些细节。 statusdue_date 是唯一可能重复的字段吗?如果是这样,下面的答案应该有效。如果没有,您可能需要指定哪些键应该与字段名称中的索引合并,哪些可以按原样拉入。

我不确定您为什么要以这种方式构建数据——使用不同的字段名称似乎会使查找数据变得困难,但暂且不论:

const data = [{
  last_name: 'User1',
  status: 'BRONZE',
  type: 'Maintenance',
  due_date: '2022-06-04 00:00:00'
}, {
  last_name: 'User1',
  status: 'BRONZE',
  type: 'Contrôle technique',
  due_date: '2022-06-18 00:00:00'
}, {
  last_name: 'User2',
  status: 'BRONZE',
  type: 'Unknow',
  due_date: null
}]

const mergedMap = {}

// Group list elements by last_name
for (const el of data) {
  if (el.last_name in mergedMap) {
    mergedMap[el.last_name].push(el)
  } else {
    mergedMap[el.last_name] = [el]
  }
}

// Iterate over "user" groups, modifying field names.
const mergedList = []
for (const last_name in mergedMap) {
  const elCount = mergedMap[last_name].length
  // If there's only one entry for this "last_name", keep it as is, 
  // then continue to next user.
  if (elCount === 1){
    mergedList.push(mergedMap[last_name][0])
    continue
  }
  const mergedUser = mergedMap[last_name].reduce((merged, el, index) => ({
    // Keep whatever keys are already here
    ...merged,
    // last_name and status are assumed to always be the same
    // for a given user, so they're safe to overwrite each time
    last_name: el.last_name,
    status: el.status,
    // type and due_date might be unique for each entry, so
    // we add an index to the field name and copy the new value in
    [`type${index + 1}`]: el.type,
    [`due_date${index + 1}`]: el.due_date,
  }), {})
  mergedList.push(mergedUser)
}

console.log(JSON.stringify(mergedList, null, 2))