专栏首页zaking's用js来实现那些数据结构01(数组篇01-数组的增删)

用js来实现那些数据结构01(数组篇01-数组的增删)

   在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念。那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记不清数组的大多数用法,只知道push,pop,shift等最基本的几个。所以,本系列(数组篇)会尽可能的让大家对数组有一个透彻的了解。也方便后面其他数据结构的学习和使用。

   可能很多web前端开发者都会有一个疑问,那就是,数组和对象究竟是数据类型?还是数据结构?那么我们就带着这样的疑问,开始下面的学习,希望看完这篇文章之后,你模糊的概念会变得清晰一些。

   首先,在js中,数据类型分为两种,基本类型(原始类型)和复杂类型,其中,基本类型是:String(字符串),Number(数值),Boolean(布尔值),还有undefinednull。复杂类型是Objecct(对象)。

  说到这里大家可能会有些疑问,只有这六种类型?那数组(Array),正则(RegExp),日期(Date)算是什么?其实他们都是Object(对象)的一个分支,换句话说它们都属于Object类型,这也正是js与众不同的地方——万物皆对象。而后面要聊的包括队列,栈,链表,集合,树,图等数据结构在js中的展现方式,也都是通过对象和原型来实现的。本文无意去详细的描述数据类型和数据结构的种类以及在js中的体现形式。所以点到为止。

  故事已经开始,请大家系好安全带,跟着我驰骋在在这篇广阔的土地上——数组

  先解释一下什么是数组吧,所谓数组,是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个“名”称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。这些无序排列的同类数据元素的集合称为数组。简单来说数组就是用于储存多个相同类型数据的集合。(当然,js中的数组也可以存储不同类型数据,但是!不建议这样做!)

  一、数组的创建和初始化

相信很多小伙伴都知道创建一个数组十分容易:

var arr = [];

  这样我们就创建了一个数组,我们还可以用new关键字来创建并初始化一个数组:

//创建一个空数组
var newArr = new Array();
//创建一个指定长度的数组
var newLenArr = new Array(4);
//创建一个具有指定参数的数组
var numArr = new Array(1,2,3,4);

  当然,通过new关键字创建并初始化数组的方式并不推荐,这里只是给大家介绍一下。其实我们通过上面第一种方式来创建数组的本质就是通过new来实例化一个Array对象。OK,这里不多说它的实现原理,还是回到数组本身来吧。

  那么我们如何读取数组中的数据呢?很简单,我就一句话带过了,也就是通过中括号([ ])arr[2],来传递数值的位置,获取到对应位置的值,也可以通过这种方式来重新赋值。

  二、数组的增删

  接下来说说如何使用js数组自带的方法来实现数组头尾的增删:push(数组尾部插入元素),unshift(数组头部插入元素),pop(数组尾部删除元素)和shift(数组头部删除元素)

  1、push方法

  如果我不想使用push方法,有没有什么方式可以在数组的尾部插入一个元素呢?其实很简单,我们只需要把值赋给数组中最后一个空位上的元素就可以了。

var nums = [0,1,2,3,4];
nums[nums.length] = 5;

  我们通过length属性,获取该数组的长度是5,但是我们数组对应的下标是从0开始的,通过这样的方式,也就给数组的尾部插入了一个新的元素。当然,其实我们可以更方便的使用push来给数组的尾部插入一个元素:

var nums = [0,1,2,3,4];
nums.push(5);

  也可以得到同样的结果。当然,push也可以传入多个参数,依次的从尾部插入数组:

var nums = [0,1,2,3,4];
nums.push(5,6,6);
//[0,1,2,3,4,5,6,6]

  2、unshift方法

  那么同样的,如何在不使用原生方法的前提下给数组的头部添加一个元素呢?

var nums = [0,1,2,3,4,5,6];
for(var i = nums.length;i >= 0;i--){
  nums[i] = nums[i - 1];      
}
//[undefined, 0, 1, 2, 3, 4, 5, 6]
nums[0] = -1;
//[-1, 0, 1, 2, 3, 4, 5, 6]

  实际上,我们通过循环遍历,把nums数组中的每一位所对应的下标增加一个,也就是向后移动一位,那么这就导致了头部的位置空出(它的位置是存在的),但是此时我们并没有给空出的位置所对应的下标赋值,所以它的长度增加了值确实undefined,赋值之后,才会得到我们想要的结果。

  下面我们还是用unshift方法来给数组的头部插入新值:

var nums = [0,1,2,3,4,5];
nums.unshift(-1);
//[-1, 0, 1, 2, 3, 4, 5]
nums.unshift(-2,-3);
//[-2, -3, -1, 0, 1, 2, 3, 4, 5]

  那么要注意一点,在使用unshift传入多个参数的时候,他会把第一个参数放在数组的头部(以此类推),也就是说unshift方法会把所有的参数依照顺序插入数组,并不是我们想当然的那样从第一个参数依次添加进数组。

  3、pop方法

  如果我想要删除数组尾部的元素,我们可以使用pop方法,其实我们还是可以用js来模拟一下pop:

var nums = [0,1,2,3,4,5];
nums.length = nums.length - 1;
//[0, 1, 2, 3, 4]

  我们可以通过手动让数组的长度减少一位,就可以实现删除数组尾部的元素,当然也可以减少两位三位等。

  实际上,在日常开发中通常都会使用pop方法来删除数组尾部的元素(pop()方法没有参数,只是删除数组尾部的元素。):

var nums = [0,1,2,3,4,5];
nums.pop()
// [0, 1, 2, 3, 4]

4、shift方法

  那么接下来我们看看如何从数组的首位删除元素:

var nums = [0,1,2,3,4,5];
for(var i = 0; i < nums.length; i++) {
    nums[i] = nums[i + 1]
}
// [1, 2, 3, 4, 5, undefined]

  可以看到,我们最后一位是undefined,也就是说在最后一次的循环里,i + 1引用了一个数组里还未初始化的位置(开辟了空间但是未赋值),所以,这样的方式只是依次覆盖了上一位的值,并没有真正的删除元素。如果想要删除首位的元素,这就需要用到shift方法了。

var nums = [0,1,2,3,4,5];
nums.shift();
// [1, 2, 3, 4, 5]

5、splice方法

  最后,我们看看如何使用splice()方法,在数组的任意位置添加和删除元素:

var nums = [0,1,2,3,4,5,6,7];
nums.splice(2);
//[0, 1]
//如果只加一个参数,说明删除从下标2开始的所有的后面的元素
var nums = [0,1,2,3,4,5,6,7];
nums.splice(2,1);
//[0, 1, 3, 4, 5, 6, 7]
//如果加入两个参数,则为删除从下标2开始的后面的几个元素。
var nums = [0,1,2,3,4,5,6,7];
nums.splice(2,1,"a","b","c");
//[0, 1, "a", "b", "c", 3, 4, 5, 6, 7]
//三个或多个参数,意味着删除从下标2(第一个参数)开始的后面的1个(第二个参数)元素,并在下标2的后面加入从第三个参数开始的后面的所有参数,把第二个参数设置为0就可以不删除元素从而实现从任意位置添加元素

  再多说一点,我们还可以使用delete操作符来删除数组中的元素,但是实际上,delete只是删除了对应下标上所存储的值,并没有同时把存储值得空间也删除掉,会导致对应位置上的值为undefined:

var nums = [0,1,2,3,4,5,6,7];
delete nums[2];
//[0, 1,  undefined, 3, 4, 5, 6, 7]

  splice()方法是修改了原数组的。

6、slice()

    slice()方法,会返回参数选定的范围的数组。该方法有两个参数,start(必选)和end(可选)。这两个值可以为负数,如果为负数则默认从尾部的第一个参数算起,也就是说-1就是数组的最后一个元素,-2就是数组的倒数第二个元素,以此类推。如果不传end,则默认从start开始直到数组最后一个元素都会被截取。

var nums = [0,1,2,3,4,5,6,6,7,"a",9,10,{name:"zaking"},["b","c"]];
var a = nums.slice(1,5);
console.log(a);//[1, 2, 3, 4]
var b = nums.slice(-1,5);
console.log(b);//[]
var c = nums.slice(-1,-5);
console.log(c);//[]
var d = nums.slice(-5,-1);
console.log(d);// ["a", 9, 10, {…}]
var f = nums.slice(5,1);
console.log(f);//[]
var x = nums.slice(5);
console.log(x);// [5, 6, 6, 7, "a", 9, 10, {…}, Array(2)]
var y = nums.slice(-5);
console.log(y)//["a", 9, 10, {…}, Array(2)]

  希望大家仔细看一下这个例子,当然,我还是一句话说明一下吧。

其实主旨就是,你所传的参数无论正负,参数所限定的范围必须是包含数组元素的。

  那么数组的一些基本用法就先介绍到这里,后面应该还有两篇左右的长度来介绍数组。花费如此的篇幅,实在是数组真的极为重要,还请大家不要着急。当真正的学会了数组之后,再去看栈,队列这种数据结构,其实就很简单了。

  最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用js来实现那些数据结构02(数组篇02-数组方法)

        上一篇文章简单的介绍了一下js的类型,以及数组的增删方法。这一篇文章,我们一起来看看数组还有哪些用法,以及在实际工作中我们可以用这些方法来做些什么。由于...

    zaking
  • 用js来实现那些数据结构03(数组篇03-排序及多维数组)

      终于,这是有关于数组的最后一篇,下一篇会真真切切给大家带来数据结构在js中的实现方式。那么这篇文章还是得啰嗦一下数组的相关知识,因为数组真的太重要了!不要怀...

    zaking
  • 用js来实现那些数据结构13(树01-二叉搜索树的实现)

      前一篇文章我们学会了第一个非顺序数据结构hashMap,那么这一篇我们来学学树,包括树的概念和一些相关的术语以及二叉搜索树的实现。唉?为什么不是树的实现,不...

    zaking
  • JavaScript强化教程——数组的基本处理函数

    本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程 —— 数组的基本处理函数

    IMWeb前端团队
  • 从零开始学 Web 之 JavaScript(四)数组

    arguements 是伪数组:不能修改长短的数组。(可以修改元素,但是不能变长变短)

    Daotin
  • 科幻电影看多了 碰到多维数组 请冷静一下

    说在前面的话:其实越是基础的知识,讲起来难度越大,因为越是基础,它就越偏向底层,你看得到的知识就那么多,但是你看不到的地方有大量的你暂时不需要知道的知识,所以只...

    用户5745563
  • 一篇文章完全掌握 JavaScript 数组操作[每日前端夜话0x87]

    可以用被称为方法的多个操作来操作数组。这些方法允许我们对数组进行添加、删除、修改挤执行更多操作。

    疯狂的技术宅
  • LeetCode第四题:删除排序数组中的重复项 II

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

    程序员小王
  • 数据结构|数组,栈和队列[1]

    数组的大小固定,如果存储数量过多,需要重建新数组;同时存储的数据类型单一,每个元素占用内存大小相同;添加,删除,移动操作比较慢,因为需要改变受影响的元素

    Rare0716
  • c语言之获取数组中元素的几种方式

    第二种方式:通过数组的地址,在C语言中,数组的名称实际上就是该数组首个元素的地址,可以通过(*名称)获取其中的值。

    绝命生

扫码关注云+社区

领取腾讯云代金券