如何在 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,但我也需要保留第二个数组的值。
您的问题缺少一些细节。 status
和 due_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))
我在 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,但我也需要保留第二个数组的值。
您的问题缺少一些细节。 status
和 due_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))