前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Html.js——数据整理】平地起高楼(蓝桥杯真题-2328)【合集】

【Html.js——数据整理】平地起高楼(蓝桥杯真题-2328)【合集】

作者头像
Rossy Yan
发布2025-02-02 21:31:05
发布2025-02-02 21:31:05
6100
代码可运行
举报
运行总次数:0
代码可运行
背景介绍

我们的国家国土面积十分的广阔,目前中国有 34 个省级行政区,包括 23 个省、5 个自治区、4 个直辖市、2 个特别行政区。其下面还有几千个县级区域,以及更多的乡镇区域。 这样层层嵌套的省市区数据在实际开发中是如何处理的呢?下面请运用所学,解开这个谜团吧~


准备步骤

本题已经内置了初始代码,打开实验环境,目录结构如下:

代码语言:javascript
代码运行次数:0
运行
复制
├── convert-to-tree.js
└── index.html

其中:

  • index.html 是主页面。
  • convert-to-tree.js 是需要补充代码的 js 文件。

目标效果

在实际开发中,由于省市区等层级较多,使得数据结构按照嵌套关系来存储则过于复杂,一般在数据库中会将省市区数据解耦,每条信息以并列关系存储在一张表中,结构如下:

代码语言:javascript
代码运行次数:0
运行
复制
[
  {
    id: "51", // 区域 id
    name: "四川省", // 区域名字
    pid: "0", // 区域的父级区域 id
  },
  {
    id: "5101",
    name: "成都市",
    pid: "51", // 成都的父级是四川省,所以 pid 是 51
  },
  // ...
];

各级行政区域通过 pid 关联起来。

但是这样平铺的数据放在前端页面展示的话,用户很难看出其中的层级关系,所以需要将平铺的结构转化为树状结构,便于前端展示:

代码语言:javascript
代码运行次数:0
运行
复制
[
  {
    id: "51", // 地址 id
    name: "四川省", // 地址名
    pid: "0", // 该地址的父节点 id
    children: [
      {
        id: "5101",
        name: "成都市",
        pid: "51",
        children: [
          {
            id: "510101",
            name: "市辖区",
            pid: "5101",
            children: [], // 如果该区域节点没有子集,children 则为空数组!!!
          },
          // ...
        ],
      },
      // ...
    ],
  },
  // ...
];

补充文件 convert-to-tree.js 中的 convertToTree 工具函数,使其实现我们需要的功能:

  • 接收平铺的区域信息数组,并将其转化为树状结构,最终数据结构如上面介绍中所示(树状结构,且对于没有子集的叶子节点,其 children 属性设置为空数组)。
  • 并且还接收一个 rootId,用于标识返回哪一个区域下面的所有节点。默认为 0 表示返回所有省份信息(在我们的示例数据中,所有省份的 pid 都为 0)。

完成后,最终页面效果如下:


要求规定

  • 题目使用 JavaScript 完成,不得使用第三方库。
  • 只能在 convert-to-tree.js 中指定区域答题,不能修改 index.html 中的任何代码。
  • 请不要修改环境自动生成的 convert-to-tree.js 以及 index.html 文件的文件路径以及文件名。
  • 检测时使用的输入数据与题目中给出的示例数据可能是不同的。考生的程序必须是通用的,不能只对需求中给定的数据有效。
  • 满足题目需求后,点击「提交检测」系统会自动判分。

判分标准

  • 本题完全实现题目目标得满分,否则得 0 分。

通关代码✔️

代码语言:javascript
代码运行次数:0
运行
复制
function convertToTree(regions, rootId = "0") {
  // 创建一个空对象,用于存储每个节点的引用
  const nodeMap = {};
  // 存储最终的树状结构
  const tree = [];

  // 遍历区域数组,将每个节点存储到 nodeMap 中,并初始化 children 属性
  regions.forEach(region => {
      // 复制一份区域信息,避免修改原始数据
      const newRegion = { ...region, children: [] };
      nodeMap[region.id] = newRegion;
  });

  // 再次遍历区域数组,建立节点之间的父子关系
  regions.forEach(region => {
      const currentNode = nodeMap[region.id];
      const parentId = region.pid;
      // 找到父节点
      const parentNode = nodeMap[parentId];

      if (parentNode) {
          // 如果父节点存在,将当前节点添加到父节点的 children 数组中
          parentNode.children.push(currentNode);
      } else if (region.pid === rootId) {
          // 如果父节点不存在且当前节点的父节点 id 等于 rootId,将当前节点添加到树的根节点
          tree.push(currentNode);
      }
  });

  return tree;
}

module.exports = convertToTree; // 检测需要,请勿删除

代码解析📑

一、Html 部分

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>平铺数据生成树状结构</title>
  </head>
  <style>
    #output-container {
      width: 600px;
    }
  </style>
  <body>
    <div id="output-container"></div>
    <script>
      module = {};
    </script>
    <script type="text/javascript" src="./convert-to-tree.js"></script>
    <script>
      const convertToTreeFn = module.exports;
      const output = document.getElementById("output-container");

      const regions = [
        // 大量的区域数据对象,每个对象包含 id、name 和 pid
        {
          id: "51",
          name: "四川省",
          pid: "0",
        },
        // 其他区域数据...
      ];
      const result = convertToTreeFn(regions);

      output.appendChild(getRegionDoms(result));

      function getRegionDoms(regions) {
        if (!regions || regions.length === 0) {
          return;
        }

        const ul = document.createElement("ul");
        regions.forEach((region) => {
          const li = document.createElement("li");
          const textNode = document.createTextNode(region.name);
          li.appendChild(textNode);
          const children = getRegionDoms(region.children);
          if (children) {
            li.appendChild(children);
          }
          ul.appendChild(li);
        });
        return ul;
      }
    </script>
  </body>
</html>
  1. <head> 部分
    • 设置字符编码为 UTF - 8,确保支持各种字符。
    • 设置浏览器兼容性和视口。
    • 定义网页标题为 “平铺数据生成树状结构”。
    • 定义了一个样式规则,将 idoutput-container 的元素宽度设置为 600px。
  2. <body> 部分
    • 创建一个 div 元素,idoutput-container,用于显示最终的树状结构数据。
    • 创建一个空的 module 对象,用于模拟 Node.js 中的模块导出机制。
    • 引入 convert-to-tree.js 文件,该文件包含将平铺数据转换为树状结构的函数。
    • 获取 convert-to-tree.js 文件中导出的 convertToTree 函数。
    • 定义一个包含大量区域数据的数组 regions,每个区域对象包含 idnamepid 属性。
    • 调用 convertToTreeFn 函数将平铺的区域数据转换为树状结构。
    • 调用 getRegionDoms 函数将树状结构的数据转换为 HTML 列表,并将其添加到 output-container 元素中。
  3. getRegionDoms 函数
    • 如果传入的 regions 数组为空或不存在,则返回 undefined
    • 创建一个 ul 元素。
    • 遍历 regions 数组,为每个区域创建一个 li 元素,并将区域名称作为文本节点添加到 li 元素中。
    • 递归调用 getRegionDoms 函数处理当前区域的子区域,并将结果添加到当前 li 元素中。
    • li 元素添加到 ul 元素中,并返回 ul 元素。

二、JavaScript 部分

代码语言:javascript
代码运行次数:0
运行
复制
function convertToTree(regions, rootId = "0") {
  // 创建一个空对象,用于存储每个节点的引用
  const nodeMap = {};
  // 存储最终的树状结构
  const tree = [];

  // 遍历区域数组,将每个节点存储到 nodeMap 中,并初始化 children 属性
  regions.forEach(region => {
      // 复制一份区域信息,避免修改原始数据
      const newRegion = { ...region, children: [] };
      nodeMap[region.id] = newRegion;
  });

  // 再次遍历区域数组,建立节点之间的父子关系
  regions.forEach(region => {
      const currentNode = nodeMap[region.id];
      const parentId = region.pid;
      // 找到父节点
      const parentNode = nodeMap[parentId];

      if (parentNode) {
          // 如果父节点存在,将当前节点添加到父节点的 children 数组中
          parentNode.children.push(currentNode);
      } else if (region.pid === rootId) {
          // 如果父节点不存在且当前节点的父节点 id 等于 rootId,将当前节点添加到树的根节点
          tree.push(currentNode);
      }
  });

  return tree;
}

module.exports = convertToTree; // 检测需要,请勿删除
  1. 函数定义
    • convertToTree 函数接受两个参数:regions 是平铺的区域数据数组,rootId 是根节点的 id,默认为 "0"
  2. 初始化变量
    • nodeMap 是一个空对象,用于存储每个节点的引用,方便后续查找。
    • tree 是一个空数组,用于存储最终的树状结构。
  3. 第一次遍历 regions 数组
    • 复制每个区域对象,并为其添加一个空的 children 属性。
    • 将复制后的区域对象存储到 nodeMap 中,键为区域的 id
  4. 第二次遍历 regions 数组
    • 获取当前区域节点和其父节点的 id
    • nodeMap 中查找父节点。
    • 如果父节点存在,将当前节点添加到父节点的 children 数组中。
    • 如果父节点不存在且当前节点的父节点 id 等于 rootId,将当前节点添加到 tree 数组中。
  5. 返回结果
    • 返回最终的树状结构数组 tree

三、工作流程 ▶️

  1. 数据准备:在 HTML 代码中定义一个包含大量区域数据的数组 regions,每个区域对象包含 idnamepid 属性。
  2. 数据转换:调用 convertToTree 函数将平铺的区域数据转换为树状结构。具体步骤如下:
    • 创建一个 nodeMap 对象,用于存储每个节点的引用。
    • 第一次遍历 regions 数组,将每个节点存储到 nodeMap 中,并初始化 children 属性。
    • 第二次遍历 regions 数组,建立节点之间的父子关系,将子节点添加到父节点的 children 数组中。
    • 将根节点添加到 tree 数组中。
  3. 数据展示:调用 getRegionDoms 函数将树状结构的数据转换为 HTML 列表,并将其添加到 output-container 元素中。具体步骤如下:
    • 创建一个 ul 元素。
    • 遍历树状结构的数据,为每个节点创建一个 li 元素,并将节点名称作为文本节点添加到 li 元素中。
    • 递归调用 getRegionDoms 函数处理当前节点的子节点,并将结果添加到当前 li 元素中。
    • li 元素添加到 ul 元素中。
    • ul 元素添加到 output-container 元素中。

通过以上步骤,实现了将平铺的省市区数据转换为树状结构,并以 HTML 列表的形式展示在网页上的功能。


测试结果👍

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 准备步骤
  • 目标效果
  • 要求规定
  • 判分标准
  • 通关代码✔️
  • 代码解析📑
    • 一、Html 部分
    • 二、JavaScript 部分
  • 测试结果👍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档