Js中遍历复杂对象的所有属性和值,并将属性构建成带children的树形结构
如下所示有一个复制对象
{
name: 'Alice',
// 一个对象中有重名的话,会以后面这个为准
// 数组不一样,可以有重复如[1,3,3,4]
name: 'acie',
age: 30,
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
},
phone: '555-1234',
interests: [
{
type: 'sports',
activities: [
{
name: '张三',
age: 50
},
{
name: '李四',
age: 80,
aaa: [
{ bbb: 'namesss' }
]
}
]
}
]
}
1、js遍历对象属性并获得属性的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>遍历复杂对象的属性遍历,f12查看结果</h1>
</div>
<script>
// 或者在浏览器中f12直接复制下面的代码(script片段中)到控制台中,回车然后就可以得到结果了
let arr = []
// 这里就相当于把属性结构变成非树形的形式,变成为一维的形式
function traverse(obj) {
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (typeof obj[prop] === 'object') {
if (Array.isArray(obj[prop])) {
obj[prop].forEach(function (item) {
traverse(item);
});
} else {
traverse(obj[prop]);
}
} else {
console.log(prop, obj[prop])
}
}
}
}
// 定义一个含有多层数组与对象的对象
let my_obj = {
name: 'Alice',
// 一个对象中有重名的话,会以后面这个为准
// 数组不一样,可以有重复如[1,3,3,4]
name: 'acie',
age: 30,
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
},
phone: '555-1234',
interests: [
{
type: 'sports',
activities: [
{
name: '张三',
age: 50
},
{
name: '李四',
age: 80,
aaa: [
{ bbb: 'namesss' }
]
}
]
}
]
};
// 调用遍历函数
traverse(my_obj);
</script>
</body>
</html>
2、将js遍历得到的属性放到数组中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>遍历复杂对象的属性遍历,f12查看结果</h1>
</div>
<script>
// 或者在浏览器中f12直接复制下面的代码(script片段中)到控制台中,回车然后就可以得到结果了
let arr = []
// 这里就相当于把属性结构变成非树形的形式,变成为一维的形式
function traverse(obj, lev, name) {
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (typeof obj[prop] === 'object') {
if (Array.isArray(obj[prop])) {
obj[prop].forEach(function (item) {
traverse(item, lev + 1, name + prop + '.');
});
} else {
traverse(obj[prop], lev + 1, name + prop + '.');
}
} else {
// console.log(prop, obj[prop])
console.log('层级:' + lev, '属性名称:' + name + prop + ' ==========值=> ' + obj[prop])
// 组装值,然后push到数组中
arr.push({ lev: lev, label: prop, name: name + prop, value: obj[prop] })
}
}
}
}
// 定义一个含有多层数组与对象的对象
let my_obj = {
name: 'Alice',
// 一个对象中有重名的话,会以后面这个为准
// 数组不一样,可以有重复如[1,3,3,4]
name: 'acie',
age: 30,
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
},
phone: '555-1234',
interests: [
{
type: 'sports',
activities: [
{
name: '张三',
age: 50
},
{
name: '李四',
age: 80,
aaa: [
{ bbb: 'namesss' }
]
}
]
}
]
};
// 调用遍历函数
traverse(my_obj, 1, '');
console.log(arr)
</script>
</body>
</html>
图中的lev表示级别,如lev:1表示一级目录,具体看下图所示即可
3、将遍历的属性构建成需要的树形结构(带children)
这里只考虑将属性变成树形结构,并不涉及到属性值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>遍历复杂对象的属性遍历,f12查看结果</h1>
</div>
<script>
// 或者在浏览器中f12直接复制下面的代码(script片段中)到控制台中,回车然后就可以得到结果了
let arr = []
// 这里就相当于把属性结构变成非树形的形式,变成为一维的形式
function traverse(obj, lev, name) {
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (typeof obj[prop] === 'object') {
if (Array.isArray(obj[prop])) {
obj[prop].forEach(function (item) {
traverse(item, lev + 1, name + prop + '.');
});
} else {
traverse(obj[prop], lev + 1, name + prop + '.');
}
} else {
// console.log(prop, obj[prop])
console.log('层级:' + lev, '属性名称:' + name + prop + ' ==========值=> ' + obj[prop])
arr.push({ lev: lev, label: prop, name: name + prop, value: obj[prop] })
}
}
}
}
// 定义一个含有多层数组与对象的对象
let my_obj = {
name: 'Alice',
// 一个对象中有重名的话,会以后面这个为准
// 数组不一样,可以有重复如[1,3,3,4]
name: 'acie',
age: 30,
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
},
phone: '555-1234',
interests: [
{
type: 'sports',
activities: [
{
name: '张三',
age: 50
},
{
name: '李四',
age: 80,
aaa: [
{ bbb: 'namesss' }
]
}
]
}
]
};
// 调用遍历函数
traverse(my_obj, 1, '');
console.log(arr)
const arr2 = arr.map(item => {
return item.name
})
console.log('这里只拿到上面遍历的到的数组中的name')
console.log(arr2)
function parsePaths(paths) {
const result = [];
for (let i = 0; i < paths.length; i++) {
const path = paths[i].split('.');
let node = result;
for (let j = 0; j < path.length; j++) {
const label = path[j];
// const value = path[j];
const existing = node.find(child => child.label === label);
if (existing) {
node = existing.children;
} else {
const newNode = { label, children: [] };
// const newNode = { label, value, children: [] };
node.push(newNode);
node = newNode.children;
}
}
}
return result;
}
const tree = parsePaths(arr2);
console.log(tree)
</script>
</body>
</html>
这里实现了分层,具体看下图所示的结果。其中children数组的长度大于0表示有子节点,具体对照下面的截图看一下就知道了,这里只是将上面的arr2数组变成树形的结构,上一个截图有arr2的结构,变成带children的树形结构
4、变成element-plus中el-cascader需要的格式
Cascader 级联选择器 | Element Plus (gitee.io)
el-cascader需要的格式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>遍历复杂对象的属性遍历,f12查看结果</h1>
</div>
<script>
// 或者在浏览器中f12直接复制下面的代码(script片段中)到控制台中,回车然后就可以得到结果了
let arr = []
// 这里就相当于把属性结构变成非树形的形式,变成为一维的形式
function traverse(obj, lev, name) {
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (typeof obj[prop] === 'object') {
if (Array.isArray(obj[prop])) {
obj[prop].forEach(function (item) {
traverse(item, lev + 1, name + prop + '.');
});
} else {
traverse(obj[prop], lev + 1, name + prop + '.');
}
} else {
// console.log(prop, obj[prop])
console.log('层级:' + lev, '属性名称:' + name + prop + ' ==========值=> ' + obj[prop])
arr.push({ lev: lev, label: prop, name: name + prop, value: obj[prop] })
}
}
}
}
// 定义一个含有多层数组与对象的对象
let my_obj = {
name: 'Alice',
// 一个对象中有重名的话,会以后面这个为准
// 数组不一样,可以有重复如[1,3,3,4]
name: 'acie',
age: 30,
address: {
street: '123 Main St',
city: 'Anytown',
state: 'CA'
},
phone: '555-1234',
interests: [
{
type: 'sports',
activities: [
{
name: '张三',
age: 50
},
{
name: '李四',
age: 80,
aaa: [
{ bbb: 'namesss' }
]
}
]
}
]
};
// 调用遍历函数
traverse(my_obj, 1, '');
console.log(arr)
const arr2 = arr.map(item => {
return item.name
})
console.log('这里只拿到上面遍历的到的数组中的name')
console.log(arr2)
function parsePaths(paths) {
const result = [];
for (let i = 0; i < paths.length; i++) {
const path = paths[i].split('.');
let node = result;
for (let j = 0; j < path.length; j++) {
const label = path[j];
const value = path[j];
const existing = node.find(child => child.label === label);
if (existing) {
node = existing.children;
} else {
// const newNode = { label, children: [] };
const newNode = { label, value, children: [] };
node.push(newNode);
node = newNode.children;
}
}
}
return result;
}
const tree = parsePaths(arr2);
console.log(tree)
</script>
</body>
</html>
至于为什么要变成这种格式,后面补充!这里暂时就这样了