webpack源码分析——truncateArgs函数

news2024/9/24 1:22:29

一、truncateArgs 函数

函数功能

该函数可以用于用户界面中的文本截断,确保长文本在有限的显示空间内能够适当显示,并且用户可以了解到部分文本已被省略。

函数参数

  • args:参数数组。用于输出到界面上
  • maxLength:当前界面上可容纳最大可输出字符长度。根据当前参数对要输出的内容进行转换(具体转换如下)

假设args中只有一个参数

let args = ['sksddsloxcc']
  • 当 0 < maxLength <=3时,输出args[0]中的字符(计算公式:[args[0].slice(-availableLength)])。比如:maxLength = 1,输出 c 。maxLength = 2 输出 cc
  • 当 3 < maxLength < arg[0].length时, 输出args[0]中的字符(计算公式:[“…” + args[0].slice(-availableLength + 3)])。比如:maxLength = 4 时,输出…c。maxLength = 5时,输出…cc
  • 当 maxLength >= arg[0].length 时,直接返回arg[0]完整字符请添加图片描述

假设args中有多个参数

let args = ['sksddsloxcc', 'dfdffrvxgsvchsgcvgcdcdsvcdbcuydcedvc', '2345vgsscgvschghgvghsgc', '35677vsgscysvcvgyvgv']

当多个参数时,truncateArgs 函数总是想着把多个参数内容,最大化输出到界面上,因此呈现如下规律。

  1. args中所有值的长度和6取最小值最后再相加的和(maxLength-参数间空格数)做比较
    maxLength - lengths.length + 1 < arraySum(lengths.map(i => Math.min(i, 6)))
    
  2. 如果界面的空间放不下,则从右向左去掉一个参数,递归(这里args中数量会有变化),再做比较,如果多个最大值6相加小于maxLength - lengths.length + 1,则进入第3步
  3. 获取当前args数组中参数字符串长度总和并和当前maxLength - lengths.length + 1比较。如果当前内容放的下就直接返回。放不下则进入第4步
    let currentLength = arraySum(args.map(a => `${a}`.length));
    // Check if all fits into maxLength
    if (currentLength <= maxLength - lengths.length + 1) return args;
    
  4. 因为当前界面放不下当前参数,于是就截断参数(args)中最长的一个。比如:‘dfdffrvxgsvchsgcvgcdcdsvcdbcuydcedvc’,截取一次做一下比较看当前参数的总长度是否小于或等于可用长度。如果时,就进行输出。不是的话就再次进行挑选参数(args)中最长的一个(注意:本次挑选最长的一个和第一次最长的一个不一定是同一个字符,因为第一次已经对它进行了截取),进行截取

最终效果如下
请添加图片描述

源码分析

  1. 对当前args数组计算每一项值的长度,存为lengths,同时获取当前界面可用长度availableLength

    const lengths = args.map(a => `${a}`.length);
    const availableLength = maxLength - lengths.length + 1;
    

    maxLength - lengths.length + 1的意思是 空格也占用空间

  2. 对args数组中只有一项并且availableLength大于0

    if (availableLength > 0 && args.length === 1) {
    	if (availableLength >= args[0].length) { // 当前界面可用长度完全够用
    		return args;
    	} else if (availableLength > 3) { // 当前界面可用长度大于3,则需要拦截并伴随'...'
    		return ["..." + args[0].slice(-availableLength + 3)];
    	} else { // 当前界面可用长度太短了,只能显示几个字符
    		return [args[0].slice(-availableLength)]; // 这里是负号,注意顺序
    	}
    }
    
  3. 多参数情况。 检查lengths中每一项之和是否超过界面可用长度,超过了进行递归

    if (availableLength < arraySum(lengths.map(i => Math.min(i, 6)))) {
    	// remove args
    	if (args.length > 1)
    		return truncateArgs(args.slice(0, args.length - 1), maxLength);
    	return [];
    }
    

    如果lengths中长度超过6时按照6算,是为了实现在不充裕的界面可用长度下该字符最多显示的数量。就是6个字符。即‘…abc’
    请添加图片描述
    当前界面可用长度为16,去掉空格剩余14。因为装不下所以输出内容,通过availableLength < arraySum(lengths.map(i => Math.min(i, 6))),判断发现可以装下args数组中前3项。所以就打印了前3项内容。至于为什么第1和3项内容有’…',下面会有说明

  4. 检查当前lengths中所有项之和是否超过界面可用长度,没有的话就全部返回。有就需要进行截断最长的项

let currentLength = arraySum(lengths);

// Check if all fits into maxLength
if (currentLength <= availableLength) return args;
  1. 截断最长的项,直到总长度符合要求为止。否则进行循环♻️
while (currentLength > availableLength) {
	const maxLength = Math.max(...lengths); // 获取当前最长项的长度
	const shorterItems = lengths.filter(l => l !== maxLength); // 过滤得到不长的项
	const nextToMaxLength =
		shorterItems.length > 0 ? Math.max(...shorterItems) : 0; // 在不长项中找到次长项(比着最长项短点)
	const maxReduce = maxLength - nextToMaxLength; // 获取最长项和次长项之间的差距
	let maxItems = lengths.length - shorterItems.length; // 获取最长项个数,因为有可能lengths有多个最长项
	let overrun = currentLength - availableLength; // 获取溢出的长度
	for (let i = 0; i < lengths.length; i++) {
		if (lengths[i] === maxLength) {
			// 这里需要比较overrun / maxItems和maxReduce的最小值,以免多减
			const reduce = Math.min(Math.floor(overrun / maxItems), maxReduce);
			lengths[i] -= reduce;
			currentLength -= reduce;
			overrun -= reduce;
			maxItems--;
		}
	}
}
  1. 对截取后的项进行输出
return args.map((a, i) => {
	const str = `${a}`;
	const length = lengths[i];
	if (str.length === length) {
		return str;
	} else if (length > 5) {
		return "..." + str.slice(-length + 3);
	} else if (length > 0) {
		return str.slice(-length);
	} else {
		return "";
	}
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1430628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue基础知识七

一 路由 1.1 生活里的路由与路由器 是为了实现多台设备上网 1.2 程序里的路由与路由器 是为了实现导航区与展示区来回切换&#xff1b; SPA单页面应用&#xff1a;就像前几章节里的项目&#xff0c;整个项目只有一个html文件&#xff1b; 案例 注意&#xff0c;最开始的时候…

嵌入式——串行外围设备接口(SPI)

目录 一、初识SPI 1. 介绍 2. 特性 补&#xff1a; 二、物理层 1. SS &#xff08;Slave Select&#xff09; 2. SCK &#xff08;Serial Clock&#xff09; 3. MOSI &#xff08;Master Output, Slave Input&#xff09; 4. MISO &#xff08;Master Input&#xff0…

AI助力农作物自动采摘,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建作物番茄采摘场景下番茄成熟度检测识别分析系统

去年十一那会无意间刷到一个视频展示的就是德国机械收割机非常高效自动化地24小时不间断地在超广阔的土地上采摘各种作物&#xff0c;专家设计出来了很多用于采摘不同农作物的大型机械&#xff0c;看着非常震撼&#xff0c;但是我们国内农业的发展还是相对比较滞后的&#xff0…

Python机器学习库(numpy库)

文章目录 Python机器学习库&#xff08;numpy库&#xff09;1. 数据的维度2. numpy基础知识2.1 numpy概述2.1 numpy概述2.1 numpy概述2.2 numpy库的引用 3. ndarray数组的创建3.1 N维数组对象ndarray3.2 创建ndarray数组3.2.1 使用Python列表、元组创建ndarray数组3.2.2 使用nu…

C++ 动态规划 线性DP 数字三角形

给定一个如下图所示的数字三角形&#xff0c;从顶部出发&#xff0c;在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点&#xff0c;一直走到底层&#xff0c;要求找出一条路径&#xff0c;使路径上的数字的和最大。 73 8 8 1 02 7 4 4 4 5 2 6 5 输入格式 …

Quick BI中lod函数之lod_include

一、lod函数简介 LOD函数的全称是详细级别表达式&#xff08;Level Of Detail Expressisons&#xff09;。它主要是为了克服一些表达式之间计算颗粒度不一致的问题。比如&#xff0c;要计算第一季度各月销售收入占比&#xff0c;这里分子计算颗粒度为’月’&#xff0c;但是分…

栈的应用:括号匹配问题_有效的括号

假设表达式中允许包含两种括号&#xff1a;圆括号和方括号&#xff0c;嵌套顺序要求&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。 考虑下列括号序列&#xff1a; 分析如下&#xff1a; 计算机…

stable diffusion学习笔记——高清修复

ai画图中通常存在以下痛点&#xff1a; 受限于本地设备的性能&#xff08;主要是显卡显存&#xff09;&#xff0c;无法跑出分辨率较高的图片。生图的时候分辨率一调大就爆显存。即便显存足够。目前主流的模型大多基于SD1.0和SD1.5&#xff0c;这些模型在训练的时候通常使用小…

机器学习-基础分类算法-KNN详解

KNN-k近邻算法 k-Nearest Neighbors 思想极度简单应用数学只是少效果好可以解释机器学习算法使用过程中的很多细节问题更完整的刻画机器学习应用的流程 创建简单测试用例 import numpy as np import matplotlib.pyplot as plt raw_data_X [[3.393533211, 2.331273381],[3.1…

单片机学习笔记---定时器和中断系统如何连起来工作

前面两节我们分别讲了中断系统和定时器&#xff0c;这节我们看看这两者连起来工作的原理。 说明&#xff1a;看这一节之前一定要先把前两节给看明白了再仔细琢磨这一节的每一张图&#xff01; 前两节&#xff1a; 单片机学习笔记---中断系统&#xff08;含外部中断&#xff…

Python基础知识:Python注释及print函数、input函数

在Python中&#xff0c;注释是对相应代码的解释&#xff0c;以增加代码的可读性&#xff0c;让用户能够更好地理解相应代码的含义。注释通过在相应代码后面加上“#”号来实现。比如以下代码 data.describe()#对数据集进行描述性分析 其中data.describe()为需要被执行的代码&a…

网络安全之漏洞扫描

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷&#xff0c;从而可以使攻击者能够在未授权的情况下访问或破坏系统。这些缺陷、错误或不合理之处可能被有意或无意地利用&#xff0c;从而对一个组织的资产或运行造成不利影响&#xff0c;如信息系统被攻击或控制…

【高阶数据结构】红黑树

文章目录 前言什么是红黑树红黑树的性质红黑树结点的定义红黑树的插入情况一情况二情况三插入代码总结 验证是否为红黑树红黑树的删除 前言 前面我们学习了 AVL 树——高度平衡的二叉搜索树&#xff0c;AVL 树保证了结点的左右子树的高度差的绝对值不超过 1&#xff0c;也就是…

Nebula Siwi:基于图数据库的智能问答助手思路分析

本文重点分析 Nebula Siwi 智能问答思路&#xff0c;具体代码可参考[2]&#xff0c;使用的数据集为 Basketballplayer[3]。部分数据和 schema 如下所示&#xff1a; 一.智能问答可实现的功能 1.Nebula Siwi 源码整体结构 主要包括前段&#xff08;Vue&#xff09;和后端&#…

Unity3d C# 在WebGL平台加载并解析xml文件实现总结

前言 xml是可扩展标记语言&#xff0c;由一系列的元素、属性、值节点等构成的一个树形结构&#xff0c;除了可读性差一点&#xff0c;别的用于存储一些结构化的数据还是比较方便的。这个功能在Unity3d端的实现是比较方便快捷的&#xff1a; void GetXML1() {string filePath …

【力扣hot100】刷题笔记Day3

前言 以撒真是一不小心就玩太久了&#xff0c;终于解锁骨哥嘞&#xff0c;抓紧来刷题&#xff0c;今天是easy双指针&#xff01; 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 一个指针遍历&#xff0c;一个指针用于交换前面的0 class Solution(object):def moveZer…

简单说说mysql的日志

今天我们通过mysql日志了解mysqld的错误日志、慢查询日志、二进制日志&#xff0c;redolog, undolog等。揭示它们的作用和用途&#xff0c;让我们工作中更能驾驭mysql。 redo 日志 如果mysql事务提交后发生了宕机现象&#xff0c;那怎么保证数据的持久性与完整性&#xff1f;…

《计算机网络简易速速上手小册》第6章:网络性能优化(2024 最新版)

文章目录 6.1 带宽管理与 QoS - 让你的网络不再拥堵6.1.1 基础知识6.1.2 重点案例&#xff1a;提高远程办公的视频会议质量实现步骤环境准备Python 脚本示例注意事项 6.1.3 拓展案例1&#xff1a;智能家居系统的网络优化实现思路Python 脚本示例 6.1.4 拓展案例2&#xff1a;提…

挑战杯 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介 今天学长向大家介绍LSTM基础 基于LSTM的预测算法 - 股票预测 天气预测 房价预测 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

Megatron-LM源码系列(七):Distributed-Optimizer分布式优化器实现Part2

1. 使用入口 DistributedOptimizer类定义在megatron/optimizer/distrib_optimizer.py文件中。创建的入口是在megatron/optimizer/__init__.py文件中的get_megatron_optimizer函数中。根据传入的args.use_distributed_optimizer参数来判断是用DistributedOptimizer还是Float16O…