本文介绍如何使用JavaScript递归函数封装一个通用的数组字段转换工具。针对简单的字段重命名及包含children的深层嵌套结构,提供了从基础map方法到递归封装的解决方案。通过示例代码展示如何处理对象内嵌对象及复杂层级,实现高效的数据结构转换。
应用场景
在实际开发中,常遇到数据字段名与前端需求不一致的情况。例如,后端返回的数组元素包含name字段,而前端组件需要的是title字段。具体数据形态如示例代码所示:
const list = [{ name: '张三' }];
// 转换为
const list = [{ title: '张三' }];
基础映射方案
最直观的处理方式是直接使用Array.prototype.map方法遍历数组,并返回包含新字段名title的新对象。这种方式代码简洁,适用于单层结构的简单转换。然而,若数组元素内部还包含children子数组,且子数组同样需要进行字段映射,map方法的递归处理能力将显得不足。鉴于此方案过于基础,此处不再展开,重点在于解决更复杂的嵌套场景。
const list = [{ name: '张三' }];
console.log(list.map(v=>{
return { title: v.name }
}));
单层与简单嵌套场景处理
参考以下代码,其中已包含详细注释说明逻辑:
核心逻辑在于根据配置项,将旧字段值绑定并赋值给新字段。进一步思考,如果list中的对象不仅包含直接字段,其children数组中的对象也包含name字段,该如何统一处理?
const list = [
{
name: '张三',
id: 6,
children: [
{ name: '张三-第一个儿子', id: 1 },
{ name: '张三-第二个儿子', id: 2 },
]
},
{
name: '李四',
id: 5,
children: [
{ name: '李四-第一个儿子', id: 3 },
{ name: '李四-第二个儿子', id: 4 },
]
}
];
/**
* props 示例: { title: 'name', children: 'children' },
* key值是生成新数组的值,value是旧数组的值
* */
function recursion(list, props) {
let data = [];
// 如果不是数据或者props为空就直接返回
if (!Array.isArray(list) || !props) return list;
// .遍历数组
for (let i = 0; i < list.length; i++) {
// 保存一个对象
let propsItem = {};
// 遍历修改值
for (const key in props) {
if (!list[i][props[key]]) continue;
propsItem[key] = list[i][props[key]];
}
data.push(propsItem);
// 如果子级是一个数组就递归赋值
if (propsItem.children && Array.isArray(propsItem.children)) {
data[i]['children'] = recursion(propsItem.children, props);
}
};
return data;
};
const res = recursion(list, {
title: 'name',
children: 'children'
});
console.log('66', res);
通用递归封装方案
观察后续示例代码可知,该封装方案不仅能处理对象直接属性的映射,也能处理对象内部嵌套对象的值提取,基本覆盖了绝大多数同类数据转换场景。阅读代码时请留意其中的注释说明,有助于理解实现细节。
const list = [
{
id: 6,
obj: { name: '张三' },
children: [
{ obj: { name: '张三-第一个儿子', }, id: 1 },
{ obj: { name: '张三-第二个儿子', }, id: 2 },
]
},
{
obj: { name: '李四' },
id: 5,
children: [
{ obj: { name: '李四-第一个儿子', }, id: 1 },
{ obj: { name: '李四-第二个儿子', }, id: 2 },
]
}
];
/**
* props 示例: { title: 'obj.name', children: 'children' },
* key值是生成新数组的值,value是旧数组的值
* */
function recursion(list, props) {
let data = [];
// 如果不是数据或者props为空就直接返回
if (!Array.isArray(list) || !props) return list;
// .遍历数组
for (let i = 0; i < list.length; i++) {
// 保存一个对象
let propsItem = {};
// 遍历修改值
for (const key in props) {
// 将字符串转为数组
const propsKey = props[key].toString().split('.');
// 如果数组大于等于2取其对象里面的值,反之直接拿key值
const propsChild = propsKey.length >= 2 ? list[i][propsKey[0]][propsKey[1]] :
propsKey.length === 1 ? list[i][propsKey[0]] : null;
// 如果为空跳槽循环
if (!propsChild) continue;
propsItem[key] = propsChild;
}
data.push(propsItem)
// 如果子级是一个数组就递归赋值
if (propsItem.children && Array.isArray(propsItem.children)) {
data[i]['children'] = recursion(propsItem.children, props);
}
};
return data;
};
const res = recursion(list, {
title: 'obj.name',
children: 'children'
});
console.log('66', res);至此,关于利用JavaScript递归函数封装通用转换场景的介绍已完成。如需了解更多相关技术细节,建议查阅本站过往文章或继续浏览后续内容。感谢支持!