使用尾递归实现javascript函数

2024-02-22

我有一个代表树的平面数组,我想使用尾递归构建一个嵌套对象。

我有以下代码可以运行并生成所需的输出,但我不确定它是否是尾递归的正确实现。

请指教 :)

const myArray = [
  { id: 'root' },
  { id: 0, parent: 'root' },
  { id: 1, parent: 'root' },
  { id: 2, parent: 0 },
  { id: 3, parent: 1 },
  { id: 4, parent: 2 },
  { id: 5, parent: 1 },
  { id: 6, parent: 4 },
  { id: 7, parent: 0 },
  { id: 8, parent: 0 },
];


function makeNestedTreeFromArray(array, id, children) {
  if (children.length <= 0) {
    return array.find(entry => entry.id === id);
  }
  return ({
    ...array.find(entry => entry.id === id),
    children: children.map(child => makeNestedTreeFromArray(
      array,
      child.id,
      array.filter(entry => entry.parent === child.id),
    ))
  });
}

const myTree = makeNestedTreeFromArray(
  myArray,
  'root',
  myArray.filter(entry => entry.parent === 'root'),
);

console.log(myTree);

尾递归的基本原理是返回具有更改的参数的相同函数。这允许用函数的新调用替换最后一个堆栈条目,而无需增加堆栈大小。

以下方法使用TCO https://stackoverflow.com/questions/310974/what-is-tail-call-optimization并返回函数调用并使用标准退出条件从函数顶部的递归函数返回。

该算法仅访问每个项目并构建具有多个根的树。最后只返回想要的根。这种方法适用于未排序的数据,因为对于每个节点,id and parent被使用并且它们的关系被保留。

function getTree(data, root, index = 0, tree = {}) {
    var o = data[index];
    if (!o) return tree[root];
    Object.assign(tree[o.id] = tree[o.id] || {}, o);
    tree[o.parent] = tree[o.parent] || {};
    tree[o.parent].children = tree[o.parent].children || [];
    tree[o.parent].children.push(tree[o.id]);
    return getTree(data, root, index + 1, tree);
}

const
    data = [{ id: 'root' }, { id: 0, parent: 'root' }, { id: 1, parent: 'root' }, { id: 2, parent: 0 }, { id: 3, parent: 1 }, { id: 4, parent: 2 }, { id: 5, parent: 1 }, { id: 6, parent: 4 }, { id: 7, parent: 0 }, { id: 8, parent: 0 }],
    tree = getTree(data, 'root');

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用尾递归实现javascript函数 的相关文章

  • 将 R (ramda) 导入 typescript .ts 文件

    我正在尝试使用Ramda js如下
  • 如何将 Django 中的数组传递给模板并在 JavaScript 中使用它

    我想将数组传递给模板 然后通过 JavaScript 使用它 In my views py I have arry1 Str 500 20 return render to response test html array1 arry1 在
  • 我如何使用 querySelector() 选择具有双类的元素

    当我想使用 querySelector 选择元素时遇到问题 ul class xoxo blogroll ul 我怎样才能选择它ul元素 在我的代码中我像这样使用 var list document body querySelector u
  • React Native:不透明视图内的透明视图

    我想用不透明框架和透明中心显示相机的视图 就像图片中的一样 黑色部分是相机的视图 我正在寻找具有纯反应本机组件的解决方案 没有额外的库 例如https github com gilbox react native masked view h
  • JavaScript - 无需布尔值即可运行一次

    有没有办法只运行一段JavaScript代码ONCE 而不使用布尔标志变量来记住它是否已经运行过 具体来说not就像是 var alreadyRan false function runOnce if alreadyRan return a
  • 如何强制折断不可折断的字符串?

    我有一个根据数据库中包含的数据生成的 HTML 页面 数据库有时包含浏览器无法分解的长字符串 因为这些字符串不包含可分解的字符 空格 点 逗号等 有没有办法使用 html css 甚至 javascript 来解决这个问题 看到这个link
  • 递归修剪对象中所有元素的更好方法?

    如果我有一个像这样的物体 const obj field subfield innerObj a asdasd asdas innerArr s ssad innerArrObj b adsad 我想出了这样的东西 const trimFi
  • 在动态创建的元素上添加事件监听器[重复]

    这个问题在这里已经有答案了 是否可以向所有动态生成的元素添加事件侦听器 Javascript 我不是页面的所有者 因此我无法以静态方式添加侦听器 对于页面加载时创建的所有元素 我使用 doc body addEventListener cl
  • React 应用程序中的 addEventListener 不起作用

    一些背景 我正在尝试消费自定义网络组件在 React 应用程序中并尝试监听来自 Web 组件的事件 我相信您不能只在自定义 Web 组件上以通常的反应方式处理事件 i e
  • window.open:是否可以打开一个新窗口并修改其 DOM

    我想打开一个新窗口 var my window open iframe html blank height 600 width 600 但当我打开它时 我想修改它的DOM 我尝试过 var div my document createEle
  • html canvas动画卡顿

    谁能解释为什么提供的画布动画断断续续 我创建了一个测试存根来演示该问题 我在桌面上的 FF Chrome IE 以及 Android 上的 FF 和 Chrome 中看到了卡顿现象 口吃是由于垃圾收集造成的吗 似乎 raf 在每次调用时都会
  • JavaScript:常量属性

    在javascript中 我可以将对象的属性声明为常量吗 这是一个示例对象 var XU Cc Components classes or function aXU this Cc Components classes var XU new
  • 将 onclick 事件应用于页面加载时不存在的元素

    我将列表样式设置为看起来像选择框 并且当用户单击列表中的元素时我想触发一个函数 但是该元素是通过加载的AJAX因此 当页面加载并且我无法绑定时不存在onclick事件到它onDomReady 如果我把它作为一个普通的选择列表 我可以只标记一
  • 有没有办法伪造同步 XHR 请求?

    我正在使用 Emscripten 系统将一堆 C 代码移植到 Javascript C 代码有很多调用fopen这是一个同步 IO 调用 在 Emscripten 中 我们使用对本地资源的 XHR 请求来模拟这一点however 在 Fir
  • 是否可以将请求标头添加到 CORS 预检请求中?

    我有一个从外部服务器 不是服务器 访问 API 的网站 为网站提供服务 通过简单的XmlHttpRequest 见下文 那个API 需要将用于访问服务的 API 密钥添加为请求标头 然而 正如这些CORS https developer m
  • Aurelia - 仅 HTML 自定义元素的内联定义

    我的 Aurelia 视图模型中有一个递归对象 如下所示 Class BottomlessPit Name string MorePits BottomlessPit null 因此 我想在 Aurelia 视图中使用递归模板 它只会在一个
  • Outlook 加载项,无法读取未定义的属性“BeginRequestEventArgs”

    我使用 Visual Studio 开发了 Outlook 插件 我的插件有一个按钮 用于填充会议邀请正文中的详细信息并添加所需的与会者 这在 99 的情况下都有效 但是 时不时地它会给我下面的 JavaScript 错误 Uncaught
  • 检测浏览器选项卡是否具有焦点

    是否有可靠的跨浏览器方法来检测选项卡是否具有焦点 场景是 我们有一个定期轮询股票价格的应用程序 如果页面没有焦点 我们可以停止轮询并为每个人节省流量噪音 特别是当人们喜欢打开具有不同投资组合的多个选项卡时 Is window onblur
  • D3 将现有 SVG 字符串(或元素)追加(插入)到 DIV

    我到处寻找这个问题的答案 并找到了一些我认为可能有用的资源 但最终没有让我找到答案 这里有一些 外部SVG http bl ocks org mbostock 1014829 嵌入SVG https stackoverflow com qu
  • 用javascript调用外部网页(跨域)

    我正在尝试使用以下网络服务来验证提要这个问题 https stackoverflow com questions 11996430 check if a url is a valid feed 但浏览器不允许我向另一台服务器发送 ajax

随机推荐

  • Dojo 1.7 如何在 require() 之外使用 dojo 组件

    我在 Dojo 1 7 2 中使用 AMD 加载程序创建了如下所示的 Dojo 小部件 var myCpane require dijit layout ContentPane function ContentPane myCpane ne
  • 单击浏览器后退按钮时如何警告用户

    我想在用户单击浏览器 后退按钮 时警告用户 然后在确认后重定向他们 下面是我的 JS 代码 但仅适用于 Firefox 我想让它也适用于 Chrome 和其他浏览器 注意 为了在 Chrome 中触发该事件 我需要首先单击页面主体 然后单击
  • 如何让机器人 DM 列出人员列表? (Discord.py)(重写)

    所以这会向我 提及的任何人发送一条私信 bot command pass context True async def pm ctx user discord User await user send hello 我如何更改它以向文本文件中
  • 使用 PyQt5,如何使 QComboBox 可搜索?

    我正在使用 PyQt5 制作 GUI 在它上面 我有一个 QComboBox 其中有一个包含 400 多个项目的下拉列表 我想知道是否有什么方法可以在 QComboBox 中输入来搜索匹配的案例 你可以使用QCompleter为了这 对于可
  • 在 Java 中旋转 NxN 矩阵

    这是破解编码面试中的一个问题 该解决方案表示 程序先旋转外边缘 然后旋转内边缘 但是 我在遵循两个 for 循环的逻辑时遇到了困难 有人可以解释代码的逻辑吗 例如为什么他们执行 layer top 和 bottom gt left 等四个步
  • 转义sql插入字符串的最佳方法?

    转义 sql 插入 更新字符串的最佳方法是什么 我想允许使用特殊字符 包括 和 在插入语句中使用每个字符串之前 搜索和替换每个字符串的最佳方法是吗 Thanks 重复 防御sql注入和跨站脚本的最佳方法 https stackoverflo
  • 如何在本地机器和minikube之间传输文件?

    我使用的是 Ubuntu 16 0 4 操作系统 并在其上安装了 minikube 我需要将一些文件复制到 minikube 那么我该怎么做呢 我尝试了下一个命令 但它询问我密码 但我不知道 scp media myuser sourceF
  • 如何安装特定版本的 H2O

    我需要安装旧版本的 H2O 因为即使版本只有一个 3 26 0 2 与 3 26 0 3 模型加载也不起作用 我正在努力寻找可以找到下载链接的页面 为什么它不存在 所有软件都有一个存档或旧版本页面 我还尝试使用当前版本的链接 但没有运气 因
  • 在网络浏览器中实现一个好的 redis 客户端需要什么?

    之前已经有人问过这个问题我可以从浏览器中运行的 JavaScript 直接连接到 Redis 服务器吗 https stackoverflow com questions 5759120 can i connect directly to
  • 如何在 Flutter 中的 Scaffold.drawer 中保存 widget 的状态?

    我想保持小部件的状态Scaffold drawer The Scaffold drawer是一个自定义小部件 它有一个升起按钮在里面 当单击按钮时 按钮中的文本发生变化 但是 当抽屉关闭并重新打开抽屉时 更改的文本将被重置 我已经使用 与A
  • Graphviz --- 边标签距离另一条边太近

    我有以下代码 其结果如下图所示 正如您所看到的 边缘和边缘标签周围有点拥挤 尤其是 a 周围 创造更多空间的最佳方法是什么 以便人们可以清楚地看到哪个标签属于哪个边缘 digraph finite state machine pad 0 2
  • “存储”REST 原型如何不创建新资源和新 URI?

    REST API 设计表明有四种资源原型 文档 集合 存储和控制器 存储不创建新资源 因此 商店永远不会生成新的 URI 一个例子 PUT users 12245 favorites boston celtics 一位用户将波士顿凯尔特人队
  • Jersey 2.26 和 Spring 4.3.10,但没有 HK2

    是否可以将 Jersey 2 26 x 配置为仅依赖 Spring 进行注入而不是 HK2 我知道 Jersey 现在与 Spring 兼容 但是是否也可以完全摆脱 HK2 不 不是 Jersey 使用了 hk2 的许多特殊功能 例如与 S
  • R 中的广义降梯度 (GRG2) 算法

    有谁知道哪个R包实现了广义降低梯度 GRG2 算法 谢谢 由于 BenBolker 已经完成了初步的工作来寻找您希望复制的功能类型 因此我发布了一个可能有用的后续内容 最近 Rhelp 上的一次交流以 R 提名的报价结束fortunes包裹
  • Android Espresso - 单击带有图像和文本的导航抽屉项目

    当导航抽屉由带有图像和文本视图的行列表组成时 如何单击导航抽屉项目 我使用了来自以下位置的 Espresso 测试源示例 git testapp test src main java com google android apps comm
  • 更新本地通知的开火日期并取消之前的通知

    我知道有几个问题here https stackoverflow com questions 5866146 remove a local notification from iphone by date and there https s
  • 如何获取主机的主IP地址?

    调用以下命令会返回所有 IP 地址的列表 Dns GetHostAddresses Dns GetHostName 有时 根据机器配置 可能会给您返回多个 IP 那么问题来了 如何确定哪个是主IP地址呢 您是否枚举了 NIC 不存在 主 I
  • 我们在 PHP 的 cURL 中使用 CURLOPT_WRITEFUNCTION 有何用处?

    您能用例子描述一下吗 我知道这是一个老问题 但也许我的回答会对您或其他人有所帮助 WRITEFUNCTION 对于处理流入的文本或根据某些条件中止下载非常有用 这是一个简单地将所有文本转换为大写字母的示例 function get html
  • 通过限制性出站防火墙建立 TCP 连接

    我正在使用 Java 创建一个使用 TCP 进行通信的客户端 服务器应用程序 客户端运行的网络具有出站防火墙 可阻止客户端连接到服务器 有什么方法 解决方法可以通过此防火墙创建 TCP 连接吗 我尝试使用开放的常见端口 例如端口 80 44
  • 使用尾递归实现javascript函数

    我有一个代表树的平面数组 我想使用尾递归构建一个嵌套对象 我有以下代码可以运行并生成所需的输出 但我不确定它是否是尾递归的正确实现 请指教 const myArray id root id 0 parent root id 1 parent