
本文深入探讨如何利用javascript的`array.prototype.reduce()`方法,将一个扁平的对象数组转换为具有多层嵌套和数据聚合的新结构。通过一个具体的医疗数据转换案例,详细解析`reduce`的工作原理,包括累加器初始化、条件查找与更新,以及如何构建复杂的嵌套对象,从而实现高效且声明式的数据重塑。
在现代Web开发中,我们经常需要对数据进行重塑以满足特定的展示或处理需求。假设我们有一个包含医疗服务记录的扁平数组,每个对象都包含medico(医生)、rateio(费率类型)、convenio(协议)和subtotal(小计)等信息。
原始数据结构示例:
const arr = [
{ medico: "med1", rateio: "rat1", convenio: "conv1", subtotal: 10 },
{ medico: "med2", rateio: "rat2", convenio: "conv2", subtotal: 10 },
{ medico: "med2", rateio: "rat2", convenio: "conv2", subtotal: 20 },
// ... 更多数据
];我们的目标是将这个扁平数组转换为一个高度结构化的嵌套对象数组,其中数据按medico分组,medico下按rateio分组,rateio下再按convenio分组,并且对相同convenio的subtotal进行求和。
目标数据结构示例:
立即学习“Java免费学习笔记(深入)”;
const result = [
{
medico: "med1",
grantotals: [
{
rateio: "rat1",
grandtotals: [
{ convenio: "conv1", sum_subtotal: 10 },
{ convenio: "conv3", sum_subtotal: 45 }
]
}
]
},
// ... 更多数据
];这种转换要求我们不仅要进行分组,还要在分组过程中对数值进行累加,并且创建多层嵌套的结构。
Array.prototype.reduce() 方法是JavaScript中一个非常强大的高阶函数,它对数组中的每个元素执行一个由您提供的“reducer”函数,将其结果汇总为单个返回值。这使得它非常适合用于构建复杂的数据结构,例如我们这里需要的嵌套聚合对象。
reduce 方法的语法如下: arr.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)
在我们的场景中,accumulator 将逐步构建出最终的嵌套结果数组。
我们将通过一个详细的reduce实现来展示如何达到目标结构。核心思想是:对于数组中的每一个原始对象,我们检查其各个层级的属性(medico, rateio, convenio)是否已存在于累加器中。如果存在,则更新相应的数据;如果不存在,则创建新的层级结构。
const arr = [
{ medico: "med1", rateio: "rat1", convenio: "conv1", subtotal: 10 },
{ medico: "med2", rateio: "rat2", convenio: "conv2", subtotal: 10 },
{ medico: "med2", rateio: "rat2", convenio: "conv2", subtotal: 20 },
{ medico: "med1", rateio: "rat1", convenio: "conv3", subtotal: 20 },
{ medico: "med1", rateio: "rat1", convenio: "conv3", subtotal: 25 },
{ medico: "med2", rateio: "rat3", convenio: "conv4", subtotal: 15 },
{ medico: "med2", rateio: "rat4", convenio: "conv3", subtotal: 10 },
];
const result = arr.reduce((acc, obj) => {
// 1. 查找或创建顶层 medico 对象
let existingMedico = acc.find((item) => item.medico === obj.medico);
if (!existingMedico) {
// 如果 medico 不存在,则创建新的 medico 对象并添加到累加器
existingMedico = {
medico: obj.medico,
grantotals: [], // 初始化 grantotals 数组
};
acc.push(existingMedico);
}
// 2. 在找到或创建的 medico 对象中,查找或创建 rateio 对象
let existingRateio = existingMedico.grantotals.find(
(item) => item.rateio === obj.rateio
);
if (!existingRateio) {
// 如果 rateio 不存在,则创建新的 rateio 对象并添加到 medico 的 grantotals
existingRateio = {
rateio: obj.rateio,
grandtotals: [], // 初始化 grandtotals 数组
};
existingMedico.grantotals.push(existingRateio);
}
// 3. 在找到或创建的 rateio 对象中,查找或创建 convenio 对象并聚合 subtotal
let existingConvenio = existingRateio.grandtotals.find(
(item) => item.convenio === obj.convenio
);
if (existingConvenio) {
// 如果 convenio 存在,则更新其 sum_subtotal
existingConvenio.sum_subtotal += obj.subtotal;
} else {
// 如果 convenio 不存在,则创建新的 convenio 对象并添加到 rateio 的 grandtotals
existingRateio.grandtotals.push({
convenio: obj.convenio,
sum_subtotal: obj.subtotal,
});
}
return acc; // 返回更新后的累加器
}, []); // 初始累加器为空数组
console.log(JSON.stringify(result, null, 2));Array.prototype.reduce()是JavaScript中一个功能强大的数组方法,它能够将一个数组转换为任何你想要的单一值或复杂数据结构。通过精心设计的累加器逻辑,我们可以实现多层分组、数据聚合和结构重塑等复杂任务。尽管在处理大规模数据时需要考虑性能优化,但对于大多数场景,reduce提供了一种简洁、声明式且高效的方式来处理数据转换需求。理解其工作原理和灵活运用是每个JavaScript开发者必备的技能。
以上就是使用JavaScript的reduce方法进行复杂数组对象转换与聚合的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号