js|无限嵌套数组/多级目录中计算有几个子元素的个数

前言

昨天做的项目中,有个需求是这样的:

项目是关于知识学习的培训平台,里面有课程和资料,课程和资料均展示多级目录(无限级) ,展示方式与B站上的视频目录同理,只不过我们需要无限级。要求在目录上方展示"共几个视频/资料"

备注:项目是Vue2的

项目页面展示和接口结构

如下图所示,这样看可能会比较直接。目录是一个数组,里面有无限个 children(子数组)children里面也会有无限层 children

下图中只有两层数组,第三层children为空,本文将以这个为例进行说明,每层用了不同颜色标注,方便对应。

备注:我只需要计算可播放的视频的总数量。
比如,如果有两层目录,第二层直接对应视频,需要计算视频的数量,第一层的目录不需计算。

实现思路

在Vue中,可以使用递归 来处理无限嵌套数组并计算其子元素的个数。
其实这就是一个普通js的写法,只是写在vue项目中。

实现方案

  1. 首先,我们需要定义一个名为countSubElements的函数(名字自定义即可,最好遵循语义化原则),该函数接收一个参数arr表示当前待统计的数组。
  2. 然后,通过判断数组的每个元素类型,如果是对象或者数组则调用自身进行递归操作;否则直接返回1(因为非对象、非数组都被视为单个子元素)。
  3. 最后将所有子元素的个数相加得到结果。

具体代码如下图:

  • 此为通用思路代码:
js 复制代码
/** 此为通用思路代码 **/

function countSubElements(arr) {
  let total = 0; // 记录子元素个数的变量
  
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i]) || typeof arr[i] === 'object') {
      total += countSubElements(arr[i]); // 递归调用自身
    } else {
      total++; // 非对象、非数组被认为是单个子元素
    }
  }
  
  return total;
}
 
// 测试样例
const nestedArr = [1, [2], [[3]], [{}, []]];
console.log('子元素个数:', countSubElements(nestedArr));
// 输出结果为:6
  • 此为适配我项目中的代码(因为我的需求是计算"视频总数量",所以只需要计算可播放的子元素即可,不需要将外层无法播放的目录计算进去)。
js 复制代码
/** 此为适配我项目中的代码 **/

// 无限多维数组数量计算
this.elementsLength = this.countSubElements(data.details); // [调用]

countSubElements(arr) {
  let total = 0; // 记录子元素个数的变量
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].children && arr[i].children.length) {
      total += this.countSubElements(arr[i].children); // 递归调用自身
    } else {
      total++; // 非对象、非数组被认为是单个子元素
    }
  }
  return total;
}

将项目中相关的所有代码全部附上

下图为页面中数量的显示位置:

所有代码如下:

html 复制代码
<div class="menu-info-right">共{{ elementsLength }}个视频</div>
js 复制代码
export default {
  data() {
    return {
      elementsLength: 0, // 统计视频/资料数量
    }
  },
  created() {
    this.getCourseInfo();
  },
  methods: {
    // 获取视频页数据
    getCourseInfo() {
      courseInfoApi({
        id: this.courseId,
      }).then(res => {
        // 无限多维数组数量计算
        this.elementsLength = this.countSubElements(data.details);
      })
    },
    // 无限多维数组length计算
    countSubElements(arr) {
      let total = 0; // 记录子元素个数的变量
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].children && arr[i].children.length) {
          total += this.countSubElements(arr[i].children); // 递归调用自身
        } else {
          total++; // 非对象、非数组被认为是单个子元素
        }
      }
      return total;
    }
  }
}

以上,希望对大家有帮助!

相关推荐
shmily麻瓜小菜鸡25 分钟前
JS/TS 易踩坑知识点 — 模块化与工程化类
开发语言·javascript·ecmascript
默_笙3 小时前
🍕 AI 的嘴巴装了水管(上):从"等它说完"到"边说边听"的流式输出指南
前端·javascript
暖焰核心3 小时前
继承全解——继承、默认成员函数、切片、隐藏与虚继承
java·前端·javascript
艾伦野鸽ggg3 小时前
前端异步请求的状态竞争(请求竞态)问题
前端·javascript·axios
是立不是利3 小时前
前端交互基石:深入剖析JavaScript三级联动背后的设计哲学
开发语言·前端·javascript
老刘的望远镜4 小时前
AgentScope Java 从零(03):Agent 的记性默认全开,我在第 50 轮翻了车
java·开发语言·javascript
前端精髓4 小时前
React 更新 state 中的对象
javascript·react.js·ecmascript
可乐鸡翅yeah_5 小时前
hls.js 播放质量埋点实战,采集卡顿、起播、错误指标定位线上用户问题
开发语言·前端·javascript·ecmascript·音视频·m3u8·音视频在线播放
Bs_MoneyMagnet7 小时前
基于springboot+vue的宠物殡葬管理平台的设计与实现 源码+文档
java·javascript·vue.js·spring boot·后端·宠物
尾善爱看海8 小时前
Vue 面试进阶篇:Composition API、插槽、自定义指令……8 个章节 + 高频面试题全解析
前端·javascript·vue.js·面试·vue