数组扩展方法(二)

news2024/11/15 19:35:58

以下将对Array.prototype上的方法进行整理,es5中数组遍历的方法在 数组扩展方法(一)可以查看

会改变原始数组

以下方法都在Array.prototype原型上

  1. push 数组尾部插入元素
  2. shift 数组首部删除元素
  3. unshift 向数组首部添加元素
  4. pop 数组尾部删除
  5. reverse 反转数组
  6. splice 删、插、替换数组
  7. sort 数组排序
  8. toString 数组转换为字符串

不会改变原数组

以下方法都在Array.prototype原型上
indexOf 获取元素索引值
lastIndexOf 获取元素索引值
conat 拼接数组
slice 截取数组
join 数组按指定符号转为字符串

工具方法

Array.prototype.indexOf

indexOf的英文意思为索引值为。
Array.prototype.indexOf:返回在数组中可以找到给定元素的第一个索引。
indexOf方法的注意事项:

  1. indexOf方法使用的是===全等运算。
  2. 注意是指定元素在数组中第一次出现的索引值。
  3. 如果指定元素不存在的话,返回-1
  4. 返回值是指定元素在数组中第一次出现的索引值,不存在时返回-1
  5. 参数问题:
    1. searchElement:指定查找的元素。
    2. fromIndex:开始查找的位置。如果该索引值大于数组长度,意味着不会在数组中查找,返回-1。如果参数中提供的索引值是一个负值,则意味将其作为数组末尾的一个抵消,即-1相当于arr.length - 1-2相当于arr.length - 2。注意:虽然fromIndex可能是负数,但是查询的顺序依旧是从前往后。如果抵消后的索引值小于0,则整个数组都会被查询,默认值为0。
const array = [2, 9, 9];

array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0
重写indexOf
Array.prototype.myIndexOf = function(){
  let arr = this,
      len = arr.length,
      item = null,
      arg1 = arguments[0],
      arg2 = arguments[1] || 0,
      i = 0;
  
  //   fromIndex:开始查找的位置。如果该索引值大于数组长度,意味着不会在数组中查找,返回-1。
  //   如果参数中提供的索引值是一个负值,则意味将其作为数组末尾的一个抵消,即-1相当于arr.length - 1,-2相当于arr.length - 2。
  //  注意:虽然fromIndex可能是负数,但是查询的顺序依旧是从前往后。如果抵销后的索引值小于0,则整个数组都会被查询,默认值为0。
  if(arg2 > len) return -1;
  if(!arg1) return -1;
  i  = arg2 < 0 ? (arg2 + len < 0 ? 0 : arg2 + len) : arg2;
  // 这里说明一点,使用for...i...遍历,会遍历出稀松数组,建议使用for...in...遍历
  for(i ; i < len ; i++){
    if(arr[i] === arg1 ){
      return i;
    }
    if(i === len - 1 && arg1 !== arr[i]){
      return -1;
    }
  }
}
const array = [2, 9, 9];
console.log(array.myIndexOf(2));   // 0
console.log(array.myIndexOf(7));     // -1
console.log(array.myIndexOf(9, 2));  // 2
console.log(array.myIndexOf(2, -1)); // -1
console.log(array.myIndexOf(2, -3)); // 0
Array.prototype.lastIndexOf

lastIndexOf的英文意思是最后的索引值。
Array.prototype.lastIndexOf:方法返回指定元素在数组中最后一个索引值。如果不存在则返回-1。从数组的后面项向前查找,从fromIndex处开始。
lastIndexOf需要我们注意的有以下几点:

  1. 参数的问题
    1. searchElement:被查找的元素。
    2. fromIndex:从此位置开始逆向查找。默认为数组的长度减1(arr.length - 1 ),即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,数组仍然会从后向前查找。如果该负值的绝对值大于数组长度,则方法返回-1,即数组不会被查找。
  2. 返回值是数组在该元素最后一次出现的索引值,如未找到返回-1.
  3. lastIndexOf使用严格相等===比较searchElement和数组中元素。
var array = [2, 5, 9, 2];
var index = array.lastIndexOf(2);
// index is 3
index = array.lastIndexOf(7);
// index is -1
index = array.lastIndexOf(2, 3);
// index is 3
index = array.lastIndexOf(2, 2);
// index is 0
index = array.lastIndexOf(2, -2);
// index is 0
index = array.lastIndexOf(2, -1);
// index is 3
重写 lastIndexOf
Array.prototype.myLastIndexOf = function(){
  let arr = this,
      len = arr.length,
      arg1 = arguments[0],
      arg2 = arguments[1] || len,
      i = 0;
  if(!arg1 || Math.abs(arg2) > len) return -1;
  // if(arg2 >= len) i = len;
  // if(arg2 < 0 ) i = arg2 + len;
  // if(0 <= arg2 < len) i = arg2;
  i = arg2 >= len ? len : (arg2 < 0 ?(arg2 + len):arg2);

  for (i; i >= 0; i--) {
    if(arg1 === arr[i]) return i;
    if(i == 0 && arg1 !== arr[i]) return -1;
  }
}

var array = [2, 5, 9, 2];
console.log(array.myLastIndexOf(2)); // 3
console.log(array.myLastIndexOf(7)); // -1
console.log(array.myLastIndexOf(2, 3)); // 3
console.log(array.myLastIndexOf(2, 2)); // 0
console.log(array.myLastIndexOf(2, -2)); // 0
console.log(array.myLastIndexOf(2, -1)); // 3
比较新颖的示例

使用lastIndexOf查找到一个元素在数组中所有的索引,并使用push将所有添加到另一个数组中。

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var searchElement = 'a';
var idx = array.lastIndexOf(searchElement);
while(idx !== -1) {
	indices.push(idx);
	idx = (idx > 0 ? array.lastIndexOf(searchElement, idx - 1) : -1);
}
console.log(indices);
Array.prototype.join

Array.prototype.join:将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
join方法需要我们注意的有以下几点:

  1. 参数问题:
    1. separator分隔符,如果需要,将分隔符转换为字符串。如果省略该值,数组元素用,分隔。如果separator是空字符串"",则所有元素之间都没有任何字符
  2. 返回值是一个数组元素连接的字符串。如果arr.length为0,则返回空字符串。
  3. 如果一个元素是undefinednull,它被转换空字符串。
  4. 这是数组转为字符串的一种方式。
示例

连接类数组对象。

function f(a, b, c) {
	var s = Array.prototype.join.call(arguments);
	console.log(s); // '1, a, true'
}
f(1, 'a', true)

undefined/null被转换为空字符串。

var arr = [undefined, null, 1];
console.log(arr.join()); // ,,1
数组扁平化

join方法带参数的话,只能将数组扁平化一层
join方法不带参数的话,直接将数组扁平化

// 带参数的话,只能将数组扁平化一层
console.log([1,[2,[3,4,5]]].join('-')); // 1-2, 3, 4, 5

// 不带参数的话,直接数据扁平化,默认分隔
console.log([1,[2,[3,4,5]]].join()); // 1, 2, 3, 4, 5
重写join方法
Array.prototype.myJoin = function (/*separator*/) {
	var t = this,
		// 保存数组索引值
		index = t.length - 1,
		// 分隔符
		separator = arguments[0] !== undefined ? arguments[0] : ',',
		// 结果字符串
		restr = '';

	// 遍历需要分割的数组
	for (var key in t) {
		if (t.hasOwnProperty(key)) {
			// 处理undefined和null问题,转为空字符串
			if (t[key] === undefined || t[key] === null) {
				restr += separator;
				continue;
			}
			// 字符串最后一个separator问题
			if (key == index) {
				restr += t[key]
				return restr;
			}
      console.log(t[key]);
			restr += t[key] + separator;
		}
	}
}

// 当一个数组被作为文本值或者进行字符串拼接操作时,将会自动调用其 toString 方法。
Array.prototype.toString

Array.prototype.toString:方法返回一个字符串,表示指定的数组及其元素。
toString方法需要我们注意的有以下几点:

  1. 无参数。
  2. 返回值是一个表示数组所有元素的字符串。
toString 方法描述

Array对象覆盖了ObjecttoString方法。对于数组对象,toString方法在内部调用join方法拼接数组中的元素中并返回一个字符串,其中包含逗号分割的每个数组元素。如果join方法不可用,或者它不是一个函数,将使用Object.prototype.toString代替,并返回[object Array]
当一个数组被作为文本值或者进行字符串拼接操作时,将会自动调用其 toString 方法。

const arr = [];
arr.join = 1;
console.log(arr.toString());

console.log(Array.prototype.toString.call({join: () => 1})); // 1
数组扁平化

toString方法能够将多维数组进行扁平化。

console.log(Array.prototype.toString.call([1, 2, 3, 4])); // 1,2,3,4
console.log(Array.prototype.toString.call([[1, 2], [3, 4]])); // 1,2,3,4
Array.from

Array.from()方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例对象。
Array.from()需要注意的有以下几点

  1. 参数问题
    1. arrayLike:想要转为数组的伪数组对象或可迭代对象。
    2. mapFn:如果制定了该参数,新数组中的每个元素都会执行该回调函数。
    3. thisArg:可选参数,执行回调mapFnthis对象。

返回值:一个新的数组实例。

// 下面是一个类似数组的对象,Array.from将它转为真正的数组。
let arrayLike = {
  '0':'a',
  '1':'b',
  '2':'c',
  length:3
}
// es6 写法
let arr2 = Array.from(arrayLike) ; // ['a','b','c']

实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。

let dom = document.querySelectorAll('div');
let domArray = Array.from(dom)

只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。

console.log(Array.from('hello')); //  ['h', 'e', 'l', 'l', 'o']
console.log('hello'.__proto__);

image.png

let namesSet = new Set(['a','b','b']);
console.log(Array.from(namesSet));
// ['a', 'b']

上面代码中,字符串和 Set 结构都具有 Iterator 接口,因此可以被Array.from转为真正的数组。
如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组。
值得提醒的是,扩展运算符(…)也可以将某些数据结构转为数组。

function foo(){
  const arg = [...arguments]
}

[...document.querySelectorAll('div')]

扩展运算符背后调用的是遍历器接口(Symbol.iterator),如果一个对象没有部署这个接口,就无法转换。Array.from方法还支持类似数组的对象。所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。

console.log(Array.from({length:3}));
// [undefined, undefined, undefined]

上面代码中,Array.from返回了一个具有三个成员的数组,每个位置的值都是undefined。扩展运算符转换不了这个对象。

  1. 重写from方法
Array.myFrom = function (iteratorObj, callback) {
	// this指向
	var thisArg = arguments[2] !== undefined ? arguments[2] : window;
	var isIterable = iteratorObj[Symbol.iterator] || iteratorObj.hasOwnProperty('length');

	// 创建一个数组
	var resArr = [];
	// 计步器
	var index = 0;
	if (isIterable) {
		if (iteratorObj.hasOwnProperty('length')) {
			for (var key in iteratorObj) {
				if (typeof callback === 'function') {
					key !== 'length' ? resArr[index] = callback.apply(thisArg, [iteratorObj[key], index++]) : '';
				}else{
          key !== 'length' ? resArr[index++] = iteratorObj[key] : ''
        }
			}
		} else {
			for (var value of iteratorObj) {
				if (typeof callback === 'function') {
					resArr[index] = callback.apply(thisArg, [value, index++]);
				}else{
          resArr[index++] = value;
        }
			}
		}
		index = 0;
	}
	return resArr;
}

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

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

相关文章

群晖docker安装sql server

安装步骤 开启群晖 SSH&#xff0c;通过 SSH 工具连接到群晖&#xff0c;运行下面的命令拉取mssql 2019 镜像 sudo docker pull mcr.microsoft.com/mssql/server:2019-latest然后在 docker 中就可以看到该镜像&#xff1a; 在群晖 docker 共享文件夹中创建 mssql2009 文件夹 …

基于SpringBoot和PotsGIS的各省地震震发可视化分析

目录 前言 一、后台接口研发 1、控制层实现 2、Mapper访问层 3、空间查询分析 二、前端可视化展示 1、主体地图定义 2、行政区划列表定义 3、行政区划定位 三、数据分析 1、北京市 2、广东省 3、青海省 4、湖南省 总结 前言 在之前的博文中&#xff0c;我们…

centos安装hadoop启动问题解决方案

1、出现了问题localhost: ERROR: JAVA_HOME is not set and could not be found. *解决方案尝试&#xff1a; 修改hadoop-env.sh&#xff08;在etc/hadoop&#xff09; sudo gedit /usr/local/hadoop/etc/hadoop/hadoop-env.sh 将原本的JAVA_HOME 替换为绝对路径就可以了 #expo…

【C语言刷题】——初识位操作符

【C语言刷题】——初识位操作符 位操作符介绍题一、 不创建临时变量&#xff08;第三个变量&#xff09;&#xff0c;实现两个数的交换&#xff08;1&#xff09;法一&#xff08;2&#xff09;法二 题二、 求一个数存储在内存中的二进制中“一”的个数&#xff08;1&#xff0…

论文阅读:FCB-SwinV2 Transformer for Polyp Segmentation

这是对FCBFormer的改进&#xff0c;我的关于FCBFormer的论文阅读笔记&#xff1a;论文阅读FCN-Transformer Feature Fusion for PolypSegmentation-CSDN博客 1&#xff0c;整体结构 依然是一个双分支结构&#xff0c;总体结构如下&#xff1a; 其中一个是全卷积分支&#xff…

浏览器缓存 四种缓存分类 两种缓存类型

浏览器缓存 本文主要包含以下内容&#xff1a; 什么是浏览器缓存按照缓存位置分类 Service WorkerMemory CacheDisk CachePush Cache 按照缓存类型分类 强制缓存协商缓存 缓存读取规则浏览器行为 什么是浏览器缓存 在正式开始讲解浏览器缓存之前&#xff0c;我们先来回顾一…

【保姆级教程】JDK安装与环境变量配置

文章目录 第一步&#xff1a;下载JDK&#xff08;以1.8为例&#xff09;第二步&#xff1a;安装第三步&#xff1a;找到默认安装目录第四步&#xff1a;配置环境变量&#xff08;win10为例&#xff09; 大家可能会遇到的疑问&#xff1a;一个电脑可以安装多个版本的jdk没有问题…

头脑风暴法是什么?10个值得推荐的头脑风暴模板!

身处职场的你&#xff0c;想必对头脑风暴这个术语并不陌生&#xff0c;它可能是某个同事或者领导的口头禅&#xff0c;每当遇到需要给出方案的场景&#xff0c;头脑风暴或者“脑暴”就会从他们嘴里脱口而出&#xff0c;但你真的了解&#xff0c;头脑风暴是什么意思吗&#xff1…

力扣刷题日志-Day2 (力扣151、43、14)

151. 反转字符串中的单词 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开 思路&#xff1a;根据题目大意&#xff0c;空格之间的就是一个单词&#xff0c;所以我们需要利用…

Sui与数据平台ZettaBlock达成合作,为其公测提供数据

Sui一向以闪电般的速度、无限水平扩展著称&#xff0c;现已迅速成为DeFi活动的重要场所。近期&#xff0c;数据平台ZettaBlock宣布在其开创性的Web3数据平台发布中&#xff0c;选择Sui作为基础集成合作伙伴之一。在ZettaBlock的开放测试版发布之际&#xff0c;构建者和开发者将…

【JAVA】HashMap扩容性能影响及优化策略

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 在软件开发中&#xff0c;HashMap是一种常用的数据结构&#xff0c;但在处理大量数据时&#xff0c;其扩容…

11、设计模式之享元模式(Flyweight)

一、什么是享元模式 享元模式是一种结构型的设计模式。它的主要目的是通过共享对象来减少系统种对象的数量&#xff0c;其本质就是缓存共享对象&#xff0c;降低内存消耗。 享元模式将需要重复使用的对象分为两个部分&#xff1a;内部状态和外部状态。 内部状态是不会变化的&…

进电子厂了,感触颇多...

作者&#xff1a;三哥 个人网站&#xff1a;https://j3code.cn 本文已收录到语雀&#xff1a;https://www.yuque.com/j3code/me-public-note/lpgzm6y2nv9iw8ec 是的&#xff0c;真进电子厂了&#xff0c;但主人公不是我。 虽然我不是主人公&#xff0c;但是我经历的过程是和主…

【2024-03-12】设计模式之模板模式的理解

实际应用场景&#xff1a;制作月饼 过程描述&#xff1a; 一开始&#xff0c;由人工制作月饼&#xff0c; 第一个&#xff1a;根据脑子里面月饼的形状&#xff0c;先涅出月饼的形状&#xff0c;然后放入面粉和馅料把开口合并起来。 第二个&#xff1a;根据脑子里面月饼的形状&…

短剧小程序系统:打造沉浸式短剧体验,开启短剧新纪元

随着移动互联网的迅猛发展&#xff0c;短剧作为一种新兴的内容形式&#xff0c;正逐渐受到广大用户的喜爱和追捧。为了满足用户对短剧内容的需求和观看体验的提升&#xff0c;短剧小程序系统应运而生&#xff0c;为用户带来了更加便捷、沉浸式的短剧观看体验。 短剧小程序系统…

如何在Linux本地搭建Tale网站并实现无公网ip远程访问

文章目录 前言1. Tale网站搭建1.1 检查本地环境1.2 部署Tale个人博客系统1.3 启动Tale服务1.4 访问博客地址 2. Linux安装Cpolar内网穿透3. 创建Tale博客公网地址4. 使用公网地址访问Tale 前言 今天给大家带来一款基于 Java 语言的轻量级博客开源项目——Tale&#xff0c;Tale…

【Python】科研代码学习:八 FineTune PretrainedModel (用 trainer,用 script);LLM文本生成

【Python】科研代码学习&#xff1a;八 FineTune PretrainedModel [用 trainer&#xff0c;用 script] LLM文本生成 自己整理的 HF 库的核心关系图用 trainer 来微调一个预训练模型用 script 来做训练任务使用 LLM 做生成任务可能犯的错误&#xff0c;以及解决措施 自己整理的 …

8块硬盘故障的存储异常恢复案例一则

关键词 华为存储、硬盘域、LUN热备冗余、重构、预拷贝 oracle rac、多路径 There are many things that can not be broken&#xff01; 如果觉得本文对你有帮助&#xff0c;欢迎点赞、收藏、评论&#xff01; 一、问题现象 近期遇到的一个案例&#xff0c;现象是一套oracl…

PXI8540高速数据采集卡

XI高速数据采集卡&#xff0c;PXI8540卡是一种基于PXI总线的模块化仪器&#xff0c;可使用PXI系统&#xff0c;在一个机箱内实现一个综合的测试系统&#xff0c;构成实验室、产品质量检测中心等各种领域的数据采集、波形分析和处理系统。也可构成工业生产过程监控系统。它的主要…