什么是递归?
递归(英语:Recursion),在数学与计算机科学中,是指在函数的定义中使用函数自身的方法
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数
其核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
一般来说,递归需要有边界条件、递归前进阶段和递归返回阶段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回
1.数组扁平化
function flattenArray(arr) {
let flattened = [];
arr.forEach(item => {
if (Array.isArray(item)) {
flattened = flattened.concat(flattenArray(item));
} else {
flattened.push(item);
}
});
return flattened;
}
// 示例用法
const nestedArray = [1, [2, [3, 4], 5], 6];
const flattenedArray = flattenArray(nestedArray);
console.log(flattenedArray);
以上代码中的 flattenArray
函数使用了递归的方式对数组进行扁平化。它遍历数组的每个元素,如果元素是数组,则递归调用 flattenArray
函数对其进行扁平化,并使用 concat
方法将扁平化后的结果合并到 flattened
数组中。如果元素不是数组,则直接将其添加到 flattened
数组中。最后,返回扁平化后的数组。
在示例中,nestedArray
是一个嵌套数组,经过 flattenArray
函数的处理,返回扁平化后的结果 [1, 2, 3, 4, 5, 6]
。
2.深拷贝
function deepCopy(obj) {
// 基本情况:如果 obj 是原始值或 null,则直接返回
if (typeof obj !== 'object' || obj === null) {
return obj;
}
// 创建一个空对象或数组,用于存储拷贝后的值
const copy = Array.isArray(obj) ? [] : {};
// 递归地拷贝对象或数组的每个属性或元素
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
// 示例用法
const originalObj = {
name: 'John',
age: 30,
address: {
city: 'New York',
country: 'USA'
}
};
const copiedObj = deepCopy(originalObj);
console.log(copiedObj);
以上代码中的 deepCopy
函数使用了递归的方式对对象进行深拷贝。它首先判断 obj 是否是原始值或 null,如果是,则直接返回原值。否则,它根据 obj 的类型创建一个空对象或数组作为拷贝后的结果。然后,它使用递归的方式对 obj 的每个属性或元素进行拷贝,通过递归调用 deepCopy
函数来处理嵌套的对象或数组。最后,返回拷贝后的对象或数组。这样就能实现对对象的递归深拷贝操作。
3.数组去重
function deduplicateArray(arr) {
// 基本情况:如果数组长度为 1 或 0,则已经是去重后的数组
if (arr.length <= 1) {
return arr;
}
// 获取数组的第一个元素
const firstElement = arr[0];
// 递归地对剩余部分进行去重
const deduplicatedRest = deduplicateArray(arr.slice(1));
// 检查剩余部分是否包含第一个元素,如果包含则移除
if (deduplicatedRest.includes(firstElement)) {
return deduplicatedRest;
} else {
return [firstElement, ...deduplicatedRest];
}
}
// 示例用法
const array = [1, 2, 2, 3, 4, 4, 5];
const deduplicatedArray = deduplicateArray(array);
console.log(deduplicatedArray); // 输出: [1, 2, 3, 4, 5]
以上代码中的 deduplicateArray
函数使用了递归的方式对数组进行去重。它首先判断数组的长度,如果长度小于等于 1,则认为数组已经是去重后的数组,直接返回。否则,它取出数组的第一个元素,然后递归地对剩余部分进行去重。最后,它检查剩余部分是否包含第一个元素,如果包含,则直接返回去重后的剩余部分,否则将第一个元素添加到去重后的结果中。这样就能实现对数组的递归去重操作。
4.数组求和
function sumArray(arr, total) {
if (arr.length === 1) {
return total
}
return sum(arr, total + arr.pop())
}
5.尾递归优化求斐波那契数列
function factorial2(n, start = 1, total = 1) {
if (n <= 2) {
return total
}
return factorial2(n - 1, total, total + start)
}
6. 数组对象格式化
let obj = {
a: '1',
b: {
c: '2',
D: {
E: '3',
},
},
}
// 转化为如下:
let obj = {
a: '1',
b: {
c: '2',
d: {
e: '3',
},
},
}
// 代码实现
function keysLower(obj) {
let reg = new RegExp('([A-Z]+)', 'g')
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
let temp = obj[key]
if (reg.test(key.toString())) {
// 将修改后的属性名重新赋值给temp,并在对象obj内添加一个转换后的属性
temp = obj[
key.replace(reg, function (result) {
return result.toLowerCase()
})
] = obj[key]
// 将之前大写的键属性删除
delete obj[key]
}
// 如果属性是对象或者数组,重新执行函数
if (typeof temp === 'object' || Object.prototype.toString.call(temp) === '[object Array]') {
keysLower(temp)
}
}
}
return obj
}