天道酬勤,学无止境

使用PHP从JSON获取父子深度级别?(Get Parent and Child depth level from JSON using PHP?)

问题

我有一个这样的树结构

树状结构

并获得这样的 JSON 值

[{"id":1,"children":[{"id":3,"children":[{"id":9,"children":[{"id":8}]}]}]},{"id":10,"children":[{"id":11,"children":[{"id":13}]},{"id":12}]}]

我需要使用 PHP 从这个 JSON 中找到该子级的子级深度级别和父级 ID。

所以我希望输出是这样的

id=>1, parent_id=>0, level=>0
id=>3, parent_id=>1, level=>1
id=>9, parent_id=>3, level=>2
id=>8, parent_id=>9, level=>3
id=>10, parent_id=>0, level=>0
id=>11, parent_id=>10, level=>1
id=>13, parent_id=>11, level=>2
id=>12, parent_id=>10, level=>1

谢谢

回答1

尝试这样的事情:

$jsonString = '[{"id":1,"children":[{"id":3,"children":[{"id":9,"children":[{"id":8}]}]}]},{"id":10,"children":[{"id":11,"children":[{"id":13}]},{"id":12}]}]';
$jsonArray = json_decode($jsonString);

function read_tree_recursively($items, $parent_id = 0, $result = array(), $level = 0) {
    foreach($items as $child) {
        $result[$child->id] = array(
            'id' => $child->id,
            'parent_id' => $parent_id,
            'level' => $level
        );

        if (!empty($child->children)) {
            $result = read_tree_recursively($child->children, $child->id, $result, $level+1);
        }
    }
    return $result;
}

// usage
read_tree_recursively($jsonArray);
标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何在广度优先搜索中跟踪深度?(How to keep track of depth in breadth first search?)
    问题 我有一棵树作为广度优先搜索的输入,我想知道随着算法的进展,它处于哪个级别? # Breadth First Search Implementation graph = { 'A':['B','C','D'], 'B':['A'], 'C':['A','E','F'], 'D':['A','G','H'], 'E':['C'], 'F':['C'], 'G':['D'], 'H':['D'] } def breadth_first_search(graph,source): """ This function is the Implementation of the breadth_first_search program """ # Mark each node as not visited mark = {} for item in graph.keys(): mark[item] = 0 queue, output = [],[] # Initialize an empty queue with the source node and mark it as explored queue.append(source) mark[source] = 1 output.append(source) # while queue is not empty while queue:
  • 在父子表单无序列表php中打印层次数据?(Print hierachical data in a parent child form unordered list php?)
    问题 我在父子层次结构中的 mysql 表中有数据; |---------+-----------+-------------| | msg_id | parent_id | msg | |---------+-----------+-------------| | 1 | NULL | msg1 | | 2 | NULL | msg2 | | 3 | NULL | msg3 | | 4 | 1 | msg1_child1 | | 5 | 1 | msg1_child2 | | 6 | 3 | msg3_child1 | |---------+-----------+-------------| 我需要以父子无序列表格式显示它,例如 -msg1 -msg1-child1 -msg2-child2 -msg2 -msg3 -msg3-child1 我该怎么做? 我需要帮助,尤其是如何在表单的层次结构中显示它。 回答1 好的从后端到前端工作...... 您可以从 php 脚本中调用一个非递归存储过程 (sproc),它会为您生成消息层次结构。 这种方法的优点是您只需要从 php 向您的数据库进行一次单一调用,而如果您使用内联 SQL,那么您将进行与级别一样多的调用(至少)。 另一个优点是,因为它是一个非递归 sproc,所以它的性能非常好,而且还可以使您的 php 代码保持整洁。 最后
  • 获取 JSON 树给定级别的节点数(Get number of nodes at given level of JSON tree)
    问题 我有一个带有子节点的 JSON 树结构,我想知道在结构的给定级别存在多少节点。 我目前有这个递归结构: var getNumNodesAtLevel = function (node, curr, desired) { if (curr === (desired - 1)) { return node.children.length; } else { var children = node.children; children.forEach(function (child) { return getNumNodesAtLevel(child, curr + 1, desired); }); } }; 这不起作用 - 任何帮助将不胜感激! 回答1 你在这里展示的方法有几个缺陷。 第一次遇到目标深度的深度时停止将只计算那里的第一组孩子,这只是一个子集。 使用诸如forEach类的迭代函数将在其迭代中进行调用,但它本身不会返回值,并且所显示的在回调中使用 return 的方法也无效。 forEach() 对每个数组元素执行一次回调函数; 与 map() 或 reduce() 不同,它总是返回未定义的值并且不可链接。 典型的用例是在链的末端执行副作用。 -MDN: Array.prototype.forEach() 更好的方法是按深度分析整个树结构的宽度,并在完成后返回索引值。
  • 当父子存储在同一个表中时显示父子关系(Display Parent-Child relationship when Parent and Child are stored in same table)
    问题 我有如下 SQL Server 表结构: ID Name ParentID ----------------------- 1 Root NULL 2 Business 1 3 Finance 1 4 Stock 3 我想在我的网页中显示详细信息,例如 ID Name ParentName ------------------------- 1 Root - 2 Business Root 3 Finance Root 4 Stock Finance 如何构建我的 SQL 查询? 回答1 试试这个... SELECT a.ID, a.Name, b.Name AS 'ParentName' FROM TABLE AS a LEFT JOIN TABLE AS b on a.ParentID = b.ID 使用左联接,查询将找不到任何要ParentName的 NULL 和ParentName列返回空白。 编辑: 如果您不希望“父”列为空,但希望显示“-”破折号,请使用此查询。 SELECT a.ID, a.Name, COALESCE(b.Name,'-') AS 'ParentName' FROM TABLE AS a LEFT JOIN TABLE AS b on a.ParentID = b.ID 回答2 假设 SQL Server 2005+,使用这样的递归 CTE:
  • 使用深度优先搜索渲染动态创建的族图而没有重叠?(Rendering a dynamically created family graph with no overlapping using a depth first search?)
    问题 我想生成这个: 使用此数据结构(id 是随机的,顺便说一下不是顺序的): var tree = [ { "id": 1, "name": "Me", "dob": "1988", "children": [4], "partners" : [2,3], root:true, level: 0, "parents": [5,6] }, { "id": 2, "name": "Mistress 1", "dob": "1987", "children": [4], "partners" : [1], level: 0, "parents": [] }, { "id": 3, "name": "Wife 1", "dob": "1988", "children": [5], "partners" : [1], level: 0, "parents": [] }, { "id": 4, "name": "son 1", "dob": "", "children": [], "partners" : [], level: -1, "parents": [1,2] }, { "id": 5, "name": "daughter 1", "dob": "", "children": [7], "partners" : [6], level: -1, "parents": [1,3] },
  • Jackson JSON序列化,通过级别定义避免递归(Jackson JSON serialization, recursion avoidance by level defining)
    问题 我使用Jackson库将我的pojo对象序列化为JSON表示形式。 例如,我有A类和B类: class A { private int id; private B b; constructors... getters and setters } class B { private int ind; private A a; constructors... getters and setters } 如果我要序列化类A中的对象,则有可能在序列化时获得递归。 我知道我可以使用@JsonIgnore停止它。 是否可以通过深度级别限制序列化? 例如,如果级别为2,则序列化将以这种方式进行: 序列化一个,级别= 0(0 <2正常)->序列化序列化ab,级别= 1(1 <2 ok)->序列化序列化ABA,级别= 2(2 <2不正确)->停止 提前致谢。 回答1 我最近遇到了一个类似的问题:杰克逊-具有双向关系的实体的序列化(避免循环) 因此,解决方案是升级到Jackson 2.0,并在类中添加以下注释: @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") public class SomeEntityClass ... 这完美地工作。 回答2
  • 通过使用超过 1 个深度级别的地图从 csv 转换为 json(Converting from csv to json by using map for more than 1 depth level)
    问题 我有一个 csv 文件,其内容如下: Fruit, Mango Fruit, Apple Car, Audi Apple, Red Color, Brown 我想最终将它转换成这样的格式: "hierarchy" : [{ "label": "Fruit", "children" : [ {label: "Mango"}, {label: "Apple", "children": [ {label:"Red"}]} ] }, { "label" : "Car", "children" : [ {label: "Audi"} ] }, { "label" : "Color", "children" : [ {label: "Brown"} ] }] 为此,我在地图中插入了值: StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append("\n"); line = br.readLine(); } String[] contents=(sb.toString().split("\n")); String[] newContents; Map<String, List<String>> myMaps =
  • MySQL所有父子关系(MySQL all parent-child relationships)
    问题 我有一个名为table 。 它有一个名为id的字段,类型为INT(11)代表行的标识符,它还有其他字段,但我认为它们与这个问题无关。 我有另一个名为table_children表。 它有一个名为parent的字段,类型为INT(11) ,将table.id作为外键引用。 它有另一个名为child类型为INT(11)字段,该字段也将table.id作为外键引用。 该表描述了table行到table行的父子关系。 这是一个可能的设置。 table table_children id parent child 0 0 1 1 1 2 2 1 3 3 3 4 4 如何在最少数量的请求中获取0的所有后代的id ? 这里的答案是1 , 2 , 3 , 4 。 感谢您的帮助。 回答1 对于 MySQL,我执行此操作的最简单方法是将所有路径存储在树中,创建一个传递闭包。 table_children parent child 0 0 1 1 2 2 3 3 4 4 0 1 0 2 0 3 0 4 1 2 1 3 1 4 3 4 现在你可以这样查询: SELECT t.* FROM table_children c JOIN table t ON c.child = t.id WHERE c.parent = 0; 也可以看看: 将平面表解析为树的最有效/最优雅的方法是什么? 使用 SQL 和
  • 如何在drupal中获取某个父级下方的所有菜单项?(how to get all the menu items below a certain parent in drupal?)
    问题 我真的只需要某个菜单项下第一级的 mlid 和标题文本。 这就是我目前正在做的事情。 (它有效,但我怀疑可能有更像 drupal 的方式。): /** * Get all the children menu items below 'Style Guide' and put them in this format: * $menu_items[mlid] = 'menu-title' * @return array */ function mymod_get_menu_items() { $tree = menu_tree_all_data('primary-links'); $branches = $tree['49952 Parent Item 579']['below']; // had to dig for that ugly key $menu_items = array(); foreach ($branches as $menu_item) { $menu_items[$menu_item['link']['mlid']] = $menu_item['link']['title']; } return $menu_items; } 有没有? 回答1 afaik,没有(我希望我错了)。 暂时,您可以通过简单地添加一个 foreach ($tree)
  • 将数据库结果转换为数组(Turn database result into array)
    问题 我刚刚为组织此表中第70页上显示的查询层次结构数据的“关闭表”方法做了“更新/添加/删除”部分:http://www.slideshare.net/billkarwin/sql-antipatterns-strike -背部 我的数据库如下所示: 表类别: ID Name 1 Top value 2 Sub value1 表类别树: child parent level 1 1 0 2 2 0 2 1 1 但是,从单个查询获取整棵树作为多维数组时,我遇到了一个问题。 这是我想回来的东西: array ( 'topvalue' = array ( 'Subvalue', 'Subvalue2', 'Subvalue3) ); ); 更新:找到了此链接,但我仍然很难将其转换为数组:http://karwin.blogspot.com/2010/03/rendering-trees-with-closure-tables.html Update2:我现在可以为每个类别添加深度,如果有帮助的话。 回答1 好的,我编写了PHP类来扩展Zend Framework DB表,行和行集类。 无论如何,我一直在开发此程序,因为我在PHP Tek-X上讲了两周有关分层数据模型的演讲。 我不想将我所有的代码发布到Stack Overflow,因为如果这样做,它们将隐式地获得知识共享许可。 更新
  • 如何通过PHP和mysql建立无限级别的菜单(How to build unlimited level of menu through PHP and mysql)
    问题 好吧,要建立我的菜单,我使用了类似这样的数据库结构 2 Services 0 3 Photo Gallery 0 4 Home 0 5 Feedback 0 6 FAQs 0 7 News & Events 0 8 Testimonials 0 81 FACN 0 83 Organisation Structure 81 84 Constitution 81 85 Council 81 86 IFAWPCA 81 87 Services 81 88 Publications 81 要为现有子菜单分配另一个子菜单,我只需将其父ID分配为其父字段的值即可。 父级0表示顶级菜单 现在在另一个子菜单中创建子菜单时没有问题 现在这是我获取顶部菜单子菜单的方式 <ul class="topmenu"> <? $list = $obj -> childmenu($parentid); //this list contains the array of submenu under $parendid foreach($list as $menu) { extract($menu); echo '<li><a href="#">'.$name.'</a></li>'; } ?> </ul> 我想做的是。 我想检查一个新菜单是否还有其他子菜单 并且我想继续检查,直到它搜索到所有可用的子菜单为止
  • 在关系数据库中存储分层数据有哪些选项?(What are the options for storing hierarchical data in a relational database?)
    问题 好的概述 一般来说,您要在快速读取时间(例如,嵌套集)或快速写入时间(邻接列表)之间做出决定。 通常,您最终会得到以下最适合您需求的选项组合。 以下提供了一些深入阅读: 另一个嵌套间隔与邻接列表的比较:我发现的邻接列表、物化路径、嵌套集和嵌套间隔的最佳比较。 分层数据模型:幻灯片很好地解释了权衡和示例用法在 MySQL 中表示层次结构:特别是对嵌套集的非常好的概述 RDBMS 中的分层数据:我见过的最全面和组织良好的一组链接,但没有太多解释 选项 我所知道的和一般特征: 邻接表: 列:ID、ParentID 易于实施。 廉价的节点移动、插入和删除。 寻找级别、祖先和后代、路径的成本很高在支持它们的数据库中通过公共表表达式避免 N+1 嵌套集(又名修改的预序树遍历) 列:左,右廉价的祖先,后代由于易失性编码,非常昂贵的O(n/2)移动、插入、删除 桥接表(又名闭包表/w 触发器) 使用单独的连接表:祖先、后代、深度(可选) 廉价的祖先和后代为插入、更新、删除写入成本O(log n) (子树的大小) 规范化编码:适用于连接中的 RDBMS 统计和查询规划器每个节点需要多行 沿袭列(又名实体化路径、路径枚举) 列:血统(例如/parent/child/grandchild/etc...) 通过前缀查询的廉价后代(例如LEFT(lineage, #) = '/enumerated
  • Linq中的分层数据-选项和性能(Hierarchical data in Linq - options and performance)
    问题 我有一些分层数据-每个条目都有一个ID和一个(可空的)父条目ID。 我想在给定条目下检索树中的所有条目。 这是在SQL Server 2005数据库中。 我在C#3.5中使用LINQ to SQL查询它。 LINQ to SQL不直接支持通用表表达式。 我的选择是使用几个LINQ查询将数据汇编为代码,或者在显示CTE的数据库上进行查看。 您认为当数据量变大时哪个选项(或另一个选项)会更好? Linq to SQL是否支持SQL Server 2008的HierarchyId类型? 回答1 我将基于CTE设置视图和关联的基于表的功能。 我的理由是,尽管您可以在应用程序端实现逻辑,但这将涉及通过网络发送中间数据以在应用程序中进行计算。 使用DBML设计器,视图可以转换为Table实体。 然后,您可以将函数与Table实体相关联,并调用在DataContext上创建的方法以派生视图定义的类型的对象。 使用基于表的功能,查询引擎在构造结果集时可以考虑您的参数,而不是事后在视图定义的结果集上应用条件。 CREATE TABLE [dbo].[hierarchical_table]( [id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, [data] [varchar](255) NOT NULL, CONSTRAINT
  • 针对树结构的优化SQL(Optimized SQL for tree structures)
    问题 您如何从性能最佳的数据库中获取树状结构的数据? 例如,假设您在数据库中具有文件夹层次结构。 其中folder-database-row具有ID , Name和ParentID列。 您是否将使用一种特殊的算法一次获取所有数据,从而最大程度地减少数据库调用并以代码进行处理? 还是您会使用对数据库的多次调用并直接从数据库中完成结构? 也许基于x的数据库行数,层次结构深度之类的答案有不同的答案? 编辑:我使用Microsoft SQL Server,但其他观点的答案也很有趣。 回答1 这实际上取决于您将如何访问树。 一种聪明的技术是给每个节点一个字符串ID,其中父代ID是子代的可预测子字符串。 例如,父级可以是“ 01”,子级可以是“ 0100”,“ 0101”,“ 0102”等。这样,您可以使用以下方法从数据库中一次选择整个子树: SELECT * FROM treedata WHERE id LIKE '0101%'; 因为条件是一个初始子字符串,所以ID列上的索引将加快查询速度。 回答2 在将树存储在RDMS中的所有方式中,最常见的是邻接表和嵌套集。 嵌套集针对读取进行了优化,并且可以在单个查询中检索整棵树。 邻接列表针对写入进行了优化,并且可以通过简单查询添加到其中。 使用邻接表,每个节点都有一个引用父节点或子节点的列(可以使用其他链接)。 使用它
  • 在 Sax XML 解析器中获取父子层次结构(Getting Parent Child Hierarchy in Sax XML parser)
    问题 我正在使用SAX(XML的简单API)来解析XML文档。 我正在获取文件具有的所有标签的输出,但我希望它在父子层次结构中显示标签。 例如:这是我的输出 <dblp> <www> <author> </author><title> </title><url> </url><year> </year></www><inproceedings> <month> </month><pages> </pages><booktitle> </booktitle><note> </note><cdrom> </cdrom></inproceedings><article> <journal> </journal><volume> </volume></article><ee> </ee><book> <publisher> </publisher><isbn> </isbn></book><incollection> <crossref> </crossref></incollection><editor> </editor><series> </series></dblp> 但是我希望它显示这样的输出(它以额外的间距显示子项(这就是我想要的样子)) <dblp> <www> <author> </author> <title> </title> <url> </url> <year> <
  • 数据库建模:如何对亚马逊等产品进行分类?(Database Modeling: How to catogorize products like Amazon?)
    问题 假设我有许多产品(从几千到几十万)需要以分层方式进行分类。 我将如何在数据库中为这样的解决方案建模? 一个简单的父子表会像这样工作吗: product_category - id - parent_id - category_name 然后在我的产品表中,我会这样做: product - id - product_category_id - name - description - price 我担心的是这不会扩展。 顺便说一下,我现在使用 MySQL。 回答1 当然它会扩展。 这将工作得很好,它是一种常用的结构。 包括一个level_no 。 这将有助于代码,但更重要的是,需要排除重复项。 如果你想要一个非常紧凑的结构,你需要类似于 Unix 的 inode 概念。 您可能难以理解生成层次结构所需的代码,例如从product ,但这是一个单独的问题。 并请改变 ( product_category )) id到product_category_id ( product id到product_id parent_id到parent_product_category_id 对评论的回应 level_no 。 看看这个数据模型,它是一个目录树结构(例如 FlieManager Explorer 窗口): 目录数据模型看看你是否能理解它,这就是 Unix inode 的概念。
  • 如何处理嵌套列表?(How do I process a nested list?)
    问题 假设我有一个这样的项目符号列表: * list item 1 * list item 2 (a parent) ** list item 3 (a child of list item 2) ** list item 4 (a child of list item 2 as well) *** list item 5 (a child of list item 4 and a grand-child of list item 2) * list item 6 我想将其解析为嵌套列表或其他一些数据结构,该结构使元素之间的父子关系变得明确(而不是取决于它们的内容和相对位置)。 例如,这是一个包含项的元组列表及其子项列表(依此类推): 编辑:希望是一个更正确的列表示例,其中列表中的每个元素都是一个元组,其中包含:项目符号的文本以及(如果适用)子级列表(以相同形式)。 [('list item 1',), ('list item 2', [('list item 3',), ('list item 4', [('list item 5',)])] ('list item 6',)] [('list item 1',), ('list item 2', [('list item 3',), ('list item 4', [('list item 5',)])]), ('list
  • 选择查询具有父子关系的类别数据(select query for category data with parent child relationship)
    问题 我有这个数据库表 CREATE TABLE IF NOT EXISTS `category` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(11) NOT NULL, `name` varchar(100) NOT NULL, `inherit` enum('Y','N') NOT NULL DEFAULT 'N', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ; -- -- Dumping data for table `category` -- INSERT INTO `category` (`id`, `parent_id`, `name`, `inherit`) VALUES (1, 0, 'Fruits', 'N'), (2, 0, 'Electronics', 'N'), (3, 0, 'Furniture', 'N'), (4, 0, 'Garden', 'N'), (5, 1, 'Apples', 'N'), (6, 1, 'Bananas', 'N'), (7, 5, 'Green Apples', 'Y'), (8, 5, 'Red Apples', 'N'), (9, 2,
  • 从 JSON 创建层次结构路径(Creating a hierarchy path from JSON)
    问题 鉴于下面的 JSON,为给定的“id”创建“名称”分层列表的最佳方法是什么? 层次结构中可以有任意数量的部分。 例如,提供 id "156" 将返回 "Add Storage Devices, Guided Configuration, Configuration" 我一直在研究使用iteritems() ,但可以借助一些帮助。 { "result": true, "sections": [ { "depth": 0, "display_order": 1, "id": 154, "name": "Configuration", "parent_id": null, "suite_id": 5 }, { "depth": 1, "display_order": 2, "id": 155, "name": "Guided Configuration", "parent_id": 154, "suite_id": 5 }, { "depth": 2, "display_order": 3, "id": 156, "name": "Add Storage Devices", "parent_id": 155, "suite_id": 5 }, { "depth": 0, "display_order": 4, "id": 160, "name": "NEW", "parent_id
  • 如何使用NSXMLParser解析具有相同名称的父子元素(How to use NSXMLParser to parse parent-child elements that have the same name)
    问题 有谁知道如何使用事件驱动的模型NSXMLParser类解析以下xml? <Node> <name> Main </name> <Node> <name> Child 1 </name> </Node> <Node> <name> Child 2 </name> </Node> </Node> 我想从此xml文件中收集所有三个名称,是否可能,或者我必须更改为基于树的解析? 回答1 这是“类型SAX”这样的解析器的常见问题,您必须手动跟踪所处XML树的当前深度。与往常一样,问题是要在其中加载整个树。内存中的DOM结构可能是不可能的,具体取决于您要处理的数据大小。 以下代码显示了完成此工作的类: #import <Foundation/Foundation.h> @interface Test : NSObject <NSXMLParserDelegate> { @private NSXMLParser *xmlParser; NSInteger depth; NSMutableString *currentName; NSString *currentElement; } - (void)start; @end 这是实现: #import "Test.h" @interface Test () - (void)showCurrentDepth; @end