数组的扁平化
原数据 var array = [[1,2,3],4,5,6,[[7]],[9,[10,[8]]]]
转化为 [ 1, 2, 3, 4, 5, 6, 7, 9, 10, 8 ]
思路: 普通递归即可实现,判断数组每一项,如果isArray继续调用自己,同时每次把最终result传递进去即可
// 递归实现
function flatten(arr, result = []) {
for (let item of arr) {
if (Array.isArray(item))
flatten(item, result)
else
result.push(item)
}
return result
}
// reduce实现
function fla(arr) {
return arr.reduce((prev, cur) => {
const re = Array.isArray(cur)? fla(cur): cur
return prev.concat(re)
}, [])
}
对象的扁平化
原数据 const obj = { a: 1, b: [1, 2, { c: true }], c: { e: 2, f: 3 }, g: null, };
转化为
{ a: 1, 'b[0]': 1, 'b[1]': 2, 'b[2].c': true, 'c.e': 2, 'c.f': 3, g: null }
思路:
兼容性判断-先判断是否是对象类型,不是的话直接返回
判断是数组的情况
判断是对象的情况
let flatten2 = (obj) => {
let result = {};
let process = (key, value) => {
// 首先判断是基础数据类型还是引用数据类型
if (Object(value) !== value) {
// 基础数据类型
if (key) {
result[key] = value;
}
} else if(Array.isArray(value)){
for (let i = 0; i< value.length; i++) {
process(`${key}[${i}]`, value[i])
}
if (value.length === 0) {
result[key] = [];
}
} else {
let objArr = Object.keys(value);
objArr.forEach(item => {
process(key?`${key}.${item}`:`${item}`, value[item])
});
if (objArr.length === 0 && key) {
result[key] = {};
}
}
}
process('', obj)
return result;
}
数组改tree
原结构
let jsonData = [
{ id: 1, parentId: 0, name: '一级菜单A' },
{ id: 2, parentId: 0, name: '一级菜单B' },
{ id: 3, parentId: 0, name: '一级菜单C' },
{ id: 4, parentId: 1, name: '二级菜单A-A' },
{ id: 5, parentId: 1, name: '二级菜单A-B' },
{ id: 6, parentId: 2, name: '二级菜单B-A' },
{ id: 7, parentId: 4, name: '三级菜单A-A-A' },
{ id: 8, parentId: 7, name: '四级菜单A-A-A-A' },
{ id: 9, parentId: 8, name: '五级菜单A-A-A-A-A' },
];
转化为
[
{
"id": 1,
"parentId": 0,
"name": "一级菜单A",
"children": [
{
"id": 4,
"parentId": 1,
"name": "二级菜单A-A",
"children": [
{
"id": 7,
"parentId": 4,
"name": "三级菜单A-A-A",
"children": [
{
"id": 8,
"parentId": 7,
"name": "四级菜单A-A-A-A",
"children": [
{
"id": 9,
"parentId": 8,
"name": "五级菜单A-A-A-A-A",
"children": []
}
]
}
]
}
]
},
{
"id": 5,
"parentId": 1,
"name": "二级菜单A-B",
"children": []
}
]
},
{
"id": 2,
"parentId": 0,
"name": "一级菜单B",
"children": [
{
"id": 6,
"parentId": 2,
"name": "二级菜单B-A",
"children": []
}
]
},
{
"id": 3,
"parentId": 0,
"name": "一级菜单C",
"children": []
}
]
实现
双层filter遍历,外层找到需要返回的id=0的跟元素,内层遍历找到外层每一个的子元素
function formatTree(obj){
let copyedObj = JSON.parse(JSON.stringify(obj)) //深拷贝源数据
return copyedObj.filter(parent=>{
let findChildren = copyedObj.filter(child=>{
return parent.id === child.parentId
})
findChildren.length>0 ? parent.children = findChildren : parent.children = []
return parent.parentId == 0 //返回顶层,依据实际情况判断这里的返回值
})
}
console.log(JSON.stringify(formatTree(jsonData), null, 3));