首页 > js array 删除指定元素_数组--学习笔记(数据结构数组 /js数组)

js array 删除指定元素_数组--学习笔记(数据结构数组 /js数组)

学习目标:

  • 了解什么是数组;
  • 数组如何访问内存地址(一维,二维);

什么是数组

由相同类型的元素的集合所组成的数据结构,分配一块连续的内存来存储。利用元素的索引可以计算出该元素对应的存储地址。 最简单的数据结构类型是一维数组。

数组如何实现随机访问?

数组是一种线性表数据结构,用一直连续的内存空间来储存一组具有相同类型的数据。

根据数组的特性(连续存储内存空间并且是线性表),才使用数组具有随机访问的特性。

缺点:

  1. 为了保持数组在内存中的连续性,使得数组插入或者删除一个数据都需要做大量的搬移工作。

数组如何根据下标实现随机访问性?

计算机会给每个内存单元分配一个地址,计算机通过地址来访问内存中的数据。当计算机需要随机访问数组中的元素时,会通过下面的寻址公式来计算该元素在内存中存储的内存地址。

a[i]_address=base_address+i*data_type_size;

其中data_type_size表示数组中每个元素的大小,比如储存的是int类型,那么data_type_size为4个字节。

数组要从0开始编号,而不是从1开始呢?

从数组储存的内存模型上来看,“下标”最确切的定义应该是“偏移 offset”。

如果数组从1开始计数,那么内存地址公式变成

a[i]_address=base_address+(i-1)*data_type_size;

不难发现需要多计算一个减法运算,对于CPU来说,就多了一条减法指令。

jvm标记清除垃圾回收算法:先记录数据需要被删除的数据(数组删除会引发数据搬移的工作,因为数组需要保持它的连续性),当数组没有更多空间存储数据时,再触发一次真正的删除操作。

JavaScript数组的特点:

JavaScript的数组,在相同类型条件下,大小没有超过它设定的是按照数据结构中的数组设置的,如果超过设置的内存或者存放不同数据类型都是使用Hash Table (Map)存储的。

  1. 支持存放不同类型数据;

有大小现在 length最大值为232 -1 --> Ecmascript 262;

1df0d3ca3fea3a1a74e666c2417bc830.png

bf89cb830c018fa1ba668257f524a3bb.png

v8引擎如何实现数组的?

  1. js数组长度是动态的,创建的时候无需声明一个固定的长度(可可以指定)。
  2. js数组可能是数组索引不连续的稀疏数组。
  3. 数用组length表示数组的长度;
  4. 对于稀疏数组,表示元素的个数。
  5. 同一个数组中可以是相同类型的元素,也可以是不相同类型的元素;

V8对数组分Fast ElementsDirctionary Elements两种存储方式进行储存。

Fast Elemeents: 传统的线性存储方式;

Fast Holey Elements: 空洞模式(存在未给元素赋值的情况--undefined);

Dirctionary Elements:Hash表存储;

length超过1024的时候转Dirctionary模式;

避免模式转换,也避免空洞模式。

数组其他事项:

  1. If length > 232 - 1, throw a RangeError exception;
  2. If length is -0, set length to +0;
  3. 数组的length属性描述符 { [[Value]]: length, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  4. 数组的属性描述符 [[Extensible]] to true.

js的数组方法

  • 数组的创建
//字面量 let arr=[1,3,5]; //构造函数 let arr1=new Array(1,3,5); let arr2=Array(1,3,5); 

Array() 和 new Array()效果一样,一个参数都是代码数组的长度,大于等于2个参数,都是代表创建数组对应的元素。

  • 数组的存取方法 indexOf() / join(),toString()/concat(),splice() :
  1. indexOf()根据值返回值所对应的下标;
  2. join(),toString() 数组转字符串;
  3. concat()合并多个数组来形成新数组,不影响原来的数组。

合并数组,如果数组是非一维数组(比如二维、三维数组),不会将它们扁平化。

let arr=new Array(8); 
let arr4=[[1,2]];console.log(arr1.concat(arr4,[5,6,7]));//[ 1, 2, 3, [ 1, 2 ], 5, 6, 7 ]
    1. splice() 截取一个数组的子集作为一个新数组,影响原来的数组;
  • 语法splice(start[, deleteCount[, item1[, item2[, ...]]]]) --- [三个参数 start/ deleteCount / item1,item2 ]
  • start为非负数的情况
    • start>=length,不会删除数组的任何元素;
  • start为非正数的情况
    • 如果start+array.length >= 0 从后开始数;
    • 如果start+array.length < 0 从0开始数;
  • 第三个参数如果不加,则表示从数组中删除元素,如果添加第三个参数,表示从数组中添加元素;
  • 可变函数 push(), unshift(), pop(), shift()
 let arr=[1,2,3,4]; 
arr.push(5,6,7);//[1,2,3,4,5,6,7]  数组的末尾添加元素//数组的头添加元素  arr.unshift(5,6,7);//[5,6,7,1,2,3,4] //此方法无参数 
arr.pop();// 数组尾删除一个元素 
arr.shift();//数组头删除一个元素
  • 迭代器方法
    • 返回新数组 map() / filter();
    • 不返回新数组 forEarch() 、every()、some()、reduce().

forEarch() 返回值undefined, 不改变原来的数组。

every()返回值为boolean值, 不改变原来的数组。每个元素都为true,才返回true。

some()返回值为boolean值, 不改变原来的数组。只有有元素为true,就返回true。

reduce()可以用来字符串拼接,求和等。

  • 二维数组

arr=[[1,2,3],[4,5,6]]; console.log(arr[1][0]); //第一个下标代表行 第二个下标代表列

参考文献:

ChromeV8引擎中Javascript数组实现分析与性能优化.pdf​max.book118.com
babc2a94084db8d0ec42f3fd50dab332.png
ArrayCreate​www.ecma-international.org

如果您觉得get到时了新知识 请我喝杯咖啡吧

wxp://f2f0ZCPViuTt3GtyInH_XBo9dMG-9J3wzdBh (二维码自动识别)

https://qr.alipay.com/fkx13050fxko05jvyheaz93 (二维码自动识别)

更多相关:

  • 一、静态数据及动态数组的创建     静态数据:               int a[10];             int a[]={1,2,3};             数组的长度必须为常量。     动态数组:             int len;             int *a=new int...

  • 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例 1: 给定 nums = [3,2,2,3], val...

  • 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 示例 1: 给定数组 nums = [1,1,2],  函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2...

  • 文章目录1. 数组的声明2. 数组元素的遍历3. 数组的截取4. Go 语言的切片5. 数组 和 切片的共同点...

  • 栈stack:stack 后入先出(LIFO) q.top()获取栈顶元素(并不删除)q.pop()删除栈顶元素q.push(x)向栈中加入元素q.empty()判断栈是否为空 队列queue:先入先出(FIFO)   q.front()获取队首元素(并不删除)q.pop()删除队首元素q.push(x)向队列中加入元素q....

  • resize(),设置大小(size); reserve(),设置容量(capacity); size()是分配容器的内存大小,而capacity()只是设置容器容量大小,但并没有真正分配内存。 打个比方:正在建造的一辆公交车,车里面可以设置40个座椅(reserve(40);),这是它的容量,但并不是说它里面就有了40个座椅,只能说...

  • v-for="(index,$i) in total" :key="$i":style="{left:`${itemWidth*((index-1)%rowItemCount)}px`,top:`${itemHeight*(Math.ceil(index/rowItemCount)-1)}px`}" //total是显示总数量 //l...

  •   技巧一(推荐指数★★★★★) 采用top、right、bottom、left,可以不在乎父元素的宽度和高度,对GPU损耗低于技巧三,但是对浏览器内存的消耗高于技巧三 .子元素 {/*父元素需要position: relative|absolute;*/position: absolute;margin: auto;to...

  • 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 push(x) – 将元素 x 推入栈中。pop() – 删除栈顶的元素。top() – 获取栈顶元素。getMin() – 检索栈中的最小元素。 示例: MinStack minStack = new MinStack(); minStack...

  • 更多内容,欢迎关注微信公众号:全菜工程师小辉~前言在笔者上一篇博客,详解了NIO,并总结NIO相比BIO的效率要高的三个原因,彻底搞懂NIO效率高的原理。这篇博客将针对第三个原因,进行更详细的讲解。首先澄清,零拷贝与内存直接映射并不是Java中独有的概念,并且这两个技术并不是等价的。零拷贝零拷贝是指避免在用户态(User-space)...

  • 一、预备知识—程序的内存分配  一个由c/C++编译的程序占用的内存分为以下几个部分  1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,如果还不清楚,那么就把它想成数组,它的内存分配是连续分配的,即,所分配的内存是在一块连续的内存区域内.当我们声明变量时,那么编译器...

  • 我的爱机是一台ThinkPad T420,原装三星DDR 1333 4G内存一根,还剩一根内存位置,最近趁京东6.18促销,准备增加一根物理内存。为了确保兼容性,觉得仍然选购DDR 1333 4G内存,于是购买了金士顿这款,比如DDR3 1600的还贵。 这个安装过程完全参照该内存的网页提示进行 这里简单记录一下,以备...

  • 陪伴我多年的老本ThinkPad T420渐渐垂垂老矣, 我想更新一下可以更新的部分, 比如将2.5寸HDD更换为SSD, 将单条4G内存再增加一根, 凡此种种想法, 可能最后归结为如何获取该笔记本的硬件配置信息, 在windows下面使用鲁大师之类的检测软件, 也许很好搞定,但是在Ubuntu 14.04平台上如果办到呢? 很简单...

  • 一.内存错误出现的场景 这几天在重构ATS插件代码的过程中遇到了烦人的内存泄露问题, 周五周六连续两天通过走查代码的方法,未能看出明显的导致内存错误的代码, 同时也觉得C和C++混合编程得到一个动态库, 在一个.cpp主文件中,即用new又用malloc来动态分配内存, 可能会导致内存错误.后来网上调研和查资料发现, new和mal...