ruby 中的树结构,父子采用数组格式,没有 gem?

2024-05-10

我有一个数组,其中包含这样的项目列表

arr = [
  {:id=>1,  :title=>"A",      :parent_id=>nil}, 
  {:id=>2,  :title=>"B",      :parent_id=>nil},
  {:id=>3,  :title=>"A1",     :parent_id=>1}, 
  {:id=>4,  :title=>"A2",     :parent_id=>1},
  {:id=>5,  :title=>"A11",    :parent_id=>3}, 
  {:id=>6,  :title=>"12",     :parent_id=>3},
  {:id=>7,  :title=>"A2=121", :parent_id=>6}, 
  {:id=>8,  :title=>"A21",    :parent_id=>4},
  {:id=>9,  :title=>"B11",    :parent_id=>2}, 
  {:id=>10, :title=>"B12",    :parent_id=>2},

... ]

如果parent_id为nil,那么它应该是父节点,如果parent_id不为nil,那么它应该位于特定的父节点下。

基于 id 和parent_id,我想提供如下响应:

-A
  -A1
    -A11
    -A12
      -A123
  -A2
    -A21
-B
  -B1
    -B11
    -B12

我怎样才能生成上面提到的响应?


这比你想象的要容易,你只需要意识到一些简单的事情:

  1. nil是一个完全有效的哈希键。
  2. 您可以使用nil作为树的虚拟根,以便所有:parent_ids 指向树上的东西。
  3. 您可以通过两种方式一次性遍历数组并跟踪条目::id and by :parent_id.

首先是一棵由哈希表示的树:

tree = Hash.new { |h,k| h[k] = { :title => nil, :children => [ ] } }

我们将从根到叶,因此我们只对父/子关系的子方感兴趣,因此:children数组中的默认值。

然后一个简单的迭代填充:titles and :children就这样:

arr.each do |n|
  id, parent_id = n.values_at(:id, :parent_id)
  tree[id][:title] = n[:title]
  tree[parent_id][:children].push(tree[id])
end

请注意,节点(包括父节点)是由以下命令自动创建的tree's default_proc第一次看到它们时,节点顺序是arr是无关紧要的。

这让我们留下了树tree钥匙在哪里:ids(包括位于nilkey),值是从该点开始的子树。

然后如果你看tree[nil][:children]剥离虚拟根,你会看到这个:

[
  { :title => "A", :children => [
    { :title => "A1", :children => [
      { :title => "A11", :children => [] },
      { :title => "12", :children => [
        { :title => "A2=121", :children => [] }  
      ] }
    ] },
    { :title => "A2", :children => [
      { :title => "A21", :children => [] }   
    ] }
  ] },
  { :title => "B", :children => [
    { :title => "B11", :children => [] },
    { :title => "B12", :children => [] }
  ] }
]

这正是您正在寻找的结构,您应该能够从那里获取它。这与您的示例响应不匹配,但那是因为您的示例arr也没有。

你也可以说:

tree = arr.each_with_object(Hash.new { |h,k| h[k] = { :title => nil, :children => [ ] } }) do |n, tree|
  #...
end

如果您更喜欢嘈杂的第一行而不是单独的tree宣言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ruby 中的树结构,父子采用数组格式,没有 gem? 的相关文章

随机推荐

  • 使用 Cypress 绕过 UI 登录

    我在绕过 UI 登录时遇到问题 我的 Web 应用程序不使用 API 来验证用户身份 没有像这样的端点 login index php只需打开登录页面并提交表单即可登录 应用程序通过以下方式对用户进行身份验证auth REQUEST use
  • 缺少“框架级别”访问修饰符

    这是场景 作为公共许可的开源 API 的创建者 我的团队创建了一个基于 Java 的 Web 用户界面框架 那么还有什么新鲜事呢 为了让事情像 Java 中那样井然有序 我们使用了具有命名约定的包 org mygroup myframewo
  • Excel VBA - 循环文件夹中的文件、复制范围、粘贴到此工作簿中

    我有 500 个包含数据的 Excel 文件 我会将所有这些数据合并到一个文件中 实现此目标的任务列表 我想循环遍历文件夹中的所有文件 打开文件 复制此范围 B3 I102 将其粘贴到活动工作簿的第一张工作表中 重复但在下面粘贴新数据 我已
  • 无论如何从变量名获取字符串?

    说我有课 interface Person NSObject NSString name 我需要获取类中 NSString 的名称 Person person Person alloc init NSLog Name of variable
  • 如何使用 JavaScript 判断大写锁定是否已打开?

    如何使用 JavaScript 判断大写锁定是否已打开 但有一个警告 我确实用谷歌搜索了它 我能找到的最好的解决方案是附加一个onkeypress事件到每个输入 然后每次检查按下的字母是否为大写 如果是 则检查是否也按住了shift 如果不
  • 在 NextJS 上运行开发服务器(在网络上)

    在使用 ReactJS 时 当我们使用命令 npm start 时 它会在 localhost 3000 以及网络 192 168 1 2 3000 上启动开发服务器 这非常简单 我可以通过进入该地址在所有设备上测试我的应用程序 最近我开始
  • 如何使用 javafx 创建响应式文本?

    我创建了一个标签 其中显示了一个数字 现在我想让这个数字响应 GUI 我怎样才能做到这一点 这是我的号码及其当前字体大小 Label label new Label label setText 12 label setFont Font f
  • 无需测试即可构建 Gradle

    我想执行gradle build不执行单元测试 我试过 gradle Dskip tests build 这似乎没有什么作用 我还可以使用其他命令吗 您应该使用 x排除任何任务的命令行参数 Try gradle build x test U
  • 为什么不使用 Interface Builder [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 模数和余数之间的差异

    我正在做一些计算 运算符在java and python 在计算时我发现 处理负数时 运算符在两种语言中的工作方式有所不同 例如 21 4 1 Java 21 4 3 Python 所以我查看了 stackoverflow 上的一些帖子 发
  • 在 jQuery UI 1.10 中的对话框标题中使用 HTML

    http jqueryui com upgrade guide 1 10 changed title option from html to text http jqueryui com upgrade guide 1 10 changed
  • Rx 中的热连接

    Observable Concat是一个连接可观察量的实现 但第二个IObservable
  • 无法创建常量值 - 只允许基本类型或枚举类型

    我在这里看到了一些与此异常相关的问题 但没有一个让我理解问题的根本原因 所以这里我们还有一个 var testquery from le in context LoanEMIs Include LoanPmnt join lp in con
  • UDP 广播发送失败:在 Linux 2.6.30 上“网络无法访问”

    我用udp广播写了一个程序 代码段如下 struct sockaddr in broadcast addr socklen t sock len sizeof broadcast addr bzero broadcast addr sock
  • 2 个具有共享 Redis 依赖的 Helm Chart

    目前 我有 2 个 Helm Charts Chart A 和 Chart B Chart A 和 Chart B 对 Redis 实例具有相同的依赖关系 如Chart yaml file dependencies name redis v
  • AppEngine:获取当前服务应用程序版本

    有没有一种简单的方法可以获取 AppEngine 中当前的服务应用程序版本 os environ CURRENT VERSION ID
  • iOS 8 UITableView 分隔符插入 0 不起作用

    我有一个应用程序 其中UITableView的分隔符插入设置为自定义值 右0 Left 0 这完美地适用于iOS 7 x 但是在iOS 8 0我看到分隔符插入设置为默认值15在右侧 即使在 xib 文件中它设置为0 它仍然显示不正确 我该如
  • 即使 if 语句中发生警报,​​if 语句中的 jQuery 代码也不会运行

    我有一个 if 语句 里面有两个警报以及一个变量赋值 当满足条件时 所有这三件事都会发生 但是当我将 jQuery 代码添加到 if 语句套件中时 该 jQuery 代码不会发生 我怎样才能得到 tabViewWindow animate
  • JavaFX 中的内部框架

    我找到了这个内部框架的例子 http docs oracle com javase tutorial uiswing components internalframe html http docs oracle com javase tut
  • ruby 中的树结构,父子采用数组格式,没有 gem?

    我有一个数组 其中包含这样的项目列表 arr id gt 1 title gt A parent id gt nil id gt 2 title gt B parent id gt nil id gt 3 title gt A1 paren