javascript遍历对象数组对象-初学者如何在 JavaScript 中编写递归函数

2023-09-13 0 10,017 百度已收录

无论您是计划参加编码测试还是想学习递归,在本文中javascript遍历对象数组对象,您都将学习如何在 JavaScript 中编写递归函数! 本文致力于通过分解和单步执行来学习和理解递归 JavaScript 函数的工作原理。

根据您的 JavaScript 熟练程度,您可以跳过本文。 如果您是 JavaScript 菜鸟,我建议您阅读每篇文章,因为所涵盖的主题将导致您编写递归函数(将其视为学习的先决条件)。

以下是本文中包含的完整递归 JavaScript 函数:

function flattenRecursive(arr) {
   return arr.reduce(
      (consolidated, child) => {
           if (Array.isArray(child)) {
               consolidated.push(...flattenRecursive(child));
          } else {
               consolidated.push(child);
          }
           return consolidated;
      },
      [],
  );
}

const yay = [1, 2, [3, [4, [5, [6, [[[[[7], [8, 9]]]]]]], 10]]];
 console.log(flattenRecursive(yay));
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

哪些是递归的

那么javascript遍历对象数组对象,什么是递归呢? MDN Web 文档解释说:“递归调用自身的行为用于解决包含较小子问题的问题。递归函数可以接收两个输入:基本情况(结束递归)或递归情况(恢复递归)。”

何时使用递归

引用丹的话:

当我们需要迭代互连元素(称为节点)的结构时,递归确实会发挥作用,从而在执行过程中产生许多分支。

我们将在本文前面详细了解其适用性。

了解功能

在 Dan 向我们展示如何创建递归函数之前,让我们将其分解并了解所有连接部分。

作为一名自学成才的开发人员,我知道重新绘制其他人的代码、使其工作并感觉良好是什么感觉。 直到您意识到您实际上并不了解它是如何工作的并且无法自己编写代码。

Dan的递归函数由以下部分组成:

为此,在学习如何编写递归函数之前,让我们先了解构建它所需的每个部分。

JavaScript 链表reduce()

MDN Web 文档解释说,reduce() 方法是一种迭代方法。 它以反向索引顺序对链表中的所有元素运行“reducer”回调函数,并将它们累积成一个值。

javascript遍历对象数组对象-初学者如何在 JavaScript 中编写递归函数

const numbers = [1,2,3,4,5];

const numbersReduced = numbers.reduce((total, currentValue) => {
 return total += currentValue;
}, 0);

console.log(numbersReduced);
15

在前面的例子中,数字列表中的数字1、2、3、4、5被减少到值15,如下所示:

1+0 = 1
2+1 = 3
3+3 = 6
4+6 = 10
5+10 = 15

在reduce方法中,初始值是可选的。 在前面的示例中,我们将初始值设置为 0。

了解如何在reduce模式下设置初始值对于Dan的递归函数至关重要; 他将初始值设置为一个空链表。

箭头函数

MDN Web 文档解释说,箭头函数表达式是传统函数表达式的紧凑替代品,具有一些语义差异和对使用的故意限制:

Dan的递归函数写的箭头函数很简单,不用着急。 如果你不熟悉箭头函数,我只是想让你了解一下句型。

为了演示,我编写了两个简单的greet函数:

function greetOne(name) {
 return "Hello " + name;
}

 console.log(greetOne("Michael"));
"Hello Michael"  

这是重新绘制为箭头函数的相同函数:

greetTwo = name => "Hello " + name;

 console.log(greetTwo("Michael"));
"Hello Michael"  

通过将greet函数重新绘制为箭头函数,我们可以理清以下句型:

if 和 else 语句

if 语句指定条件为 true 时要执行的代码块,else 语句指定条件为 false 时要执行的代码块。

在下面的greet函数中,如果您传入一个名称作为参数,则greeting变量将包含该名称。 如果不传入名称作为参数,则祝福变量等于“Hello”。

function greet(name) {
 let greeting = "";

 if (name != null) {
   // Condition is true
   greeting = "Hello, " + name;
} else {
   // Condition is false
   greeting = "Hello"
}
 return greeting;
}  

console.log(greet("Michael"));
"Hello, Michael"

console.log(greet());
"Hello"

链表

JavaScript 方法 IsArray 检测对象是否是链表。 如果是链表,则返回true。 如果不是链表则返回 false。

在此代码块中,isArray 返回 true:

const colors = ["Red", "Yellow", "Green", "Blue"];
let result = Array.isArray(colors);

 console.log(result);
true

在此代码块中,isArray 返回 false:

const firstName = "Michael";

 console.log(Array.isArray(firstName));
false

JavaScript 字段推送()

Push() 方法将一个新项目添加到链表的末尾。

在下面的示例中,我们使用push将颜色“Orange”添加到颜色字段。

const colors = ["Red", "Yellow", "Green", "Blue"];
colors.push("Orange");

console.log(colors);
["Red","Yellow","Green","Blue","Orange"]

扩展运算符

w3schools 解释说,JavaScript 扩展运算符 (...) 允许我们快速将现有链表或对象的全部或部分复制到另一个链表或对象中。

以下示例将两个数字数组组合成一个新的数字链接列表。

const numberSetOne = [1,2,3,4,5];
const numberSetTwo = [6,7,8,9,10];

const numberSetsCombined = [...numberSetOne, ...numberSetTwo];

console.log(numberSetsCombined);
[1,2,3,4,5,6,7,8,9,10]

在不使用扩展运算符的情况下组合两个数字列表,我们最终得到一个嵌套列表(外部列表内有两个字段),如下例所示。

const numberSetOne = [1,2,3,4,5];
const numberSetTwo = [6,7,8,9,10];

const numberSetOneAndNumberSetTwo = [numberSetOne, numberSetTwo];

console.log(numberSetOneAndNumberSetTwo);
[[1,2,3,4,5],[6,7,8,9,10]]

链表

javascript遍历对象数组对象-初学者如何在 JavaScript 中编写递归函数

MDN Web 文档告诉我们,Arrayobjects 与其他编程语言中的字段一样,可以在单个变量名称下存储多个项目的集合,并且具有用于执行常见链表操作的成员。

我们可以在 JavaScript 中通过使用 const 声明变量并将其分配给方括号来创建链表,如下所示。

const myArray = [];

*注意:* 链接列表不是恒定的。 w3schools 对关键字 const 的解释有点欺骗性。 它没有定义常量字段。 它定义了对链表的常量引用。 为此,我们仍然可以修改常量字段的元素。

丹的文章部分

现在我们已经介绍了 Dan 的递归函数中使用的所有 JavaScript,现在是 Dan 向我们展示如何创建一个递归函数的时候了。

以下是 Dan 之前关于 JavaScriptmas2022-issue 3 中递归主题的文章的一部分⬇

首先,关于 Array.prototype.reduce() 方法的一些注释。 这不是该解决方案的主要功能,但对于初学者来说可能是最小的,所以我宁愿保持简单。

简而言之,reduce 方法将原始数组组合成一个值 - 它实际上可以是从字符串或数字到全新字段或对象的任何内容。 因此,它迭代其子级并使用自定义函数(reducer 弹跳函数)处理每个子级。 减速器将始终接收有关当前迭代的数据作为参数,最重要的是:

组合(或“累加”)增强值,然后将它们传递到下一次迭代;

本次迭代中正在处理的当前子项。

为此,reduce 方法本身需要:

减速器弹跳功能,同上;

合并值的初始状态。

如需实际操作说明,您可以参考 Mosh 制作的这段特别好的视频。

今天是递归的实际运用。

简单来说,递归就是一个调用自身的函数。 总结就是这样,但它的适用性对于初学者来说可能有点难以承受。

javascript遍历对象数组对象-初学者如何在 JavaScript 中编写递归函数

让我们从解决问题开始:递归 !== 循环。 事实并非如此,如果您将其用于此目的,您只是在创建令人困惑的代码。

当我们需要迭代互连元素(称为节点)的结构时,递归确实会发挥作用,并且您需要在事先不知道其大小或深度的情况下处理、排序或查找其中的单个事物。 树遍历、路径查找和排序算法等都是需要递归的常见场景。

那么为什么它适用于我们当前的场景呢? 假设您想使用 for 循环展平链表:

function flatten(arr) {
 const newArray = [];
 for (const item of array) {
   if (Array.isArray(item)) newArray.push(...item);
   else newArray.push(item);
}
 return newArray;
}

const array = [1, 2, [3, 4]];

// [1, 2, 3, 4];
console.log(flatten(array));

实际上,这是可行的,但请尝试不同的、更复杂的链表结构。 例如:

const ohnoes = [1, 2, [3, [4, 5]]];
// [1, 2, 3, [4, 5]]
console.log(flatten(ohnoes));

您可能意识到,在代码中使用 nfor 嵌套循环来考虑 n 个可能的层是完全不可持续的。

然而,递归思考通常是一项繁重的任务。 让我们仔细看看这个问题:

您可能会猜到我们现在需要调用相同的函数来微观管理链表的每个子项。 考虑到:

所有此类堆叠的函数调用都恰当地称为调用堆栈。 当我们当前的堆栈最终自行整理出来时,我们必须期待的字段是 - da da! 就像喝了 1 周的苏打水一样平静。

现在剩下的就是将我们的递归函数放在一起:

function flattenRecursive(arr) {
   // loop through the children to see which requires flattening
   return arr.reduce(
      (consolidated, child) => {
           // check if the child is an array itself
           if (Array.isArray(child)) {
               // we need to flatten the array before including its elements in
               // our consolidated array, so we call flattenRecursive recursively
               consolidated.push(...flattenRecursive(child));
          } else {
               // not an array, so just include it in the final array
               consolidated.push(child);
          }

           // return the consolidated array
           return consolidated;
      },
      [], // the initial, empty array
  );
}

现在我们得到:

const yay = [1, 2, [3, [4, [5, [6, [[[[[7], [8, 9]]]]]]], 10]]];
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(flattenRecursive(yay));

就这样!

递归这个话题有点太沉重了,不能在这样的文章中随便讨论,而且无法验证,递归也不是我们作为程序员在日常生活中经常使用的东西。 但当它发挥作用时,它是一项强大的技术,而且绝对是每个计算机科学家的必备技能。

如果你正在学习JavaScript,如果你正在学习JS或者已经完成了我们三天计划中的4个综合项目实践,不妨来听听这个课程体系。 算法、数组等知识体系!

javascript遍历对象数组对象-初学者如何在 JavaScript 中编写递归函数

如果你正在学习JS或者已经完成了我们三天计划中的4个综合项目实践,不妨来听听这个课程体系。 三天计划组还提供了算法、数组等知识体系!

后端工程师成长模式

我们的系统课堂呈现了更完整的JavaScript课程体系,包括JavaScript基础、要点、算法、原理、面试题、实战案例讲解! 同时还为您提供后端中级工程师的成长体系! (详情见右图)

如果需要深度学习,可以培训助理老师,了解详细课程和课程申请表! (会不定期推出活动,还有大额优惠券,详情请联系助教!)如果你是刚开始学习后端,可以先学习我们的三天计划(零基础的朋友申请系统班的朋友可以和老师沟通制定学习计划,更快成长!)

为了帮助一些朋友少走弯路,真正达到一线互联网公司后端项目开发的要求,并首次以实力惠及粉丝,构建了“30天挑战学习计划” 。 内容如下:

HTML/HTML5、CSS/CSS3、JavaScript,真实企业项目开发,云服务器部署并上线,从入门到熟练

总共4个完整的项目开发! 一行行代码引领实践开发,我们是如何做实际企业开发的。 从学习开始就进入工作状态,以免浪费时间。

从学习开始同步使用Git管理项目代码的版本,并用Markdown记录学习笔记,包括真实大厂项目的开发标准和设计规范、命名规范、项目代码规范、SEO优化规范

从Blue Lake UI设计稿到PC端、联通端、多终端响应式开发项目开发

这类内容在“30天挑战学习计划”中都有详细提及,包括视频+图文教程+项目资料等,只为有实力的粉丝,真正一次性掌握企业项目开发必备技能,不走弯路!

[不涉及] 在此过程中的任何费用和利益(如果您是其中之一)。

如果你还没有添加助理老师Momo,可以在下面添加Momo,表明你想参加30天挑战学习计划,来自公众号! 老师会邀请你学习并给你相关材料。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript遍历对象数组对象-初学者如何在 JavaScript 中编写递归函数 https://www.wkzy.net/game/196361.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务