递归实现对象的结构复制


前言

Q : 什么是对象结构?
A:像下面的代码就是一个json,而json的结构就是对象结构(如:objHome 下有name、obj、arr等属性并且其属性也可以有子级属性)

let objHome = {
    
    
    name: '123213',
    nulls: null,
    obj: {
    
    
        test: 21123,
        tee: {
    
    
            te: 'erer'
        }
    },
    arr: [234, 2, 34, 'df'],
    arr2: [{
    
    
            arrName: '1111',
            arrObj: {
    
    
                arrTee: '4343'
            }
        },
        {
    
    
            arrName: '22222',
            arrObj: {
    
    
                arrTee: '24234'
            }
        }
    ]
}

Q : 对象结构复制能实现什么效果?
A:如下图,将json的结构复制可重新生成相同结构的数据

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、如何实现

说明:实现的方式有许多种,这里使用递归来实现

实现思路:
step1: 将对象进行遍历(这样我们能获取到第一层的键和值)
step2: 创建递归实现获取子级对象/数组下的对象的键
step3: 对新值进行添加数据

step1

我们这里随便使用一个json格式的数据并将其遍历如下:

在这里插入图片描述

//相关代码
let objHome = {
    
    
    name: '123213',
    nulls: null,
    obj: {
    
    
        test: 21123,
        tee: {
    
    
            te: 'erer'
        }
    },
    arr: [234, 2, 34, 'df'],
    arr2: [{
    
    
            arrName: '1111',
            arrObj: {
    
    
                arrTee: '4343'
            }
        },
        {
    
    
            arrName: '22222',
            arrObj: {
    
    
                arrTee: '24234'
            }
        }
    ]
}
for (const key in objHome) {
    
    
    console.log('key===>',key);
}

step2

创建递归实现获取json及其子级对象/数组对象的key

在这里插入图片描述

//修改代码,将遍历修改为以下代码
const getKeys = (obj) => {
    
    
    if ((typeof obj) != 'object') return;//这里需要限制一下进来的只能是object类型
    for (const key in obj) {
    
    
        console.log('key===>', key);
        const val = obj[key];
        // 需要判断它的值是否为null
        // 判断它的类型,如果是object则说明其可能拥有子级
        if (val && (typeof val) == 'object') {
    
    
            // 进入这里说明该属性可能有子级,这时我们需要进行递归直到没有为止
            // 注意一点:如果值为数组对象时我们只需取其第一项即可
            // 通过length即可判断是object or  array
            getKeys(val.length ? val[0] : val);
        }
    }
}
getKeys(objHome);

step3

在递归中对新值进行添加数据

(1).在对新值进行添加数据前我们先实现一个简单的效果(只需简单的一步)—>如何修改一个json的所有值(即:key所对应的value) Ps:这效果实现了,那么对新值进行添加数据也就不难了

在这里插入图片描述

//修改代码
const getKeys = (obj) => {
    
    
    if ((typeof obj) != 'object') return;//这里需要限制一下进来的只能是object类型
    for (const key in obj) {
    
    
        // console.log('key===>', key);
        const val = obj[key];
        // 需要判断它的值是否为null
        // 判断它的类型,如果是object则说明其可能拥有子级
        if (val && (typeof val) == 'object') {
    
    
            // 进入这里说明该属性可能有子级,这时我们需要进行递归直到没有为止
            // 注意一点:如果值为数组对象时我们只需取其第一项即可
            // 通过length即可判断是object or  array
            getKeys(val.length ? val[0] : val);
        }else{
    
    
            obj[key]='acqui';
        }
    }
}
getKeys(objHome);
console.log(objHome);

(2).在对新值进行添加数据前我们需要考虑到一个问题:上一步(修改值)我们是在原有的结构基础上进行修改的这显得比较容易。而对新值进行添加数据没有上一个父级

  • 如果我们像上一步操作结果是这样的:(这显然不是我们要的效果)
    在这里插入图片描述
  • 思考…之前的是有结构的而现在对新值进行赋值是没有结构,所以我们需要对新值的结构进行处理。而结构就会涉及到father和son,那么只要我们在判断到当前key所对应到的value为object时向新值中添加一个json。如果当前key所对应到的value不为object时向当前所在json中添加值就行了。

在这里插入图片描述

代码整理

效果已经实现了,现在我们对代码进行整理一下:

let objHome = {
    
    
    name: '123213',
    nulls: null,
    obj: {
    
    
        test: 21123,
        tee: {
    
    
            te: 'erer'
        }
    },
    arr: [234, 2, 34, 'df'],
    arr2: [{
    
    
            arrName: '1111',
            arrObj: {
    
    
                arrTee: '4343'
            }
        },
        {
    
    
            arrName: '22222',
            arrObj: {
    
    
                arrTee: '24234'
            }
        }
    ]
}

let newObj = [];
const getKeys = (obj, father) => {
    
    
    if ((typeof obj) != 'object') return; //这里需要限制一下进来的只能是object类型
    for (const key in obj) {
    
    
        // console.log('key===>', key);
        const val = obj[key];
        // 需要判断它的值是否为null
        // 判断它的类型,如果是object则说明其可能拥有子级
        if (val && (typeof val) == 'object') {
    
    
            const curentVal = {
    
    
                label: key,
                children: []
            }
            father ? father.push(curentVal) : newObj.push(curentVal);
            // 进入这里说明该属性可能有子级,这时我们需要进行递归直到没有为止
            // 注意一点:如果值为数组对象时我们只需取其第一项即可
            // 通过length即可判断是object or  array
            getKeys(val.length ? val[0] : val, curentVal.children);
        } else {
    
    
            father ? father.push({
    
    
                label: key
            }) : newObj.push({
    
    
                label: key
            });
        }
    }
}
getKeys(objHome);
console.log(newObj);
console.log(newObj[2].children);

总结

遇到需要多次循环时使用递归能够很好的解决。但递归需要你的逻辑保持清晰,明白当前这一步是在做什么

猜你喜欢

转载自blog.csdn.net/z1783883121/article/details/120879578