• 用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)]

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

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

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

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

  • 相关阅读:
    Java遍历Map键、值。获取Map大小的方法
    Oracle CASE WHEN 用法介绍
    JS动态改变select选择变更option的index值
    js对select动态添加和删除OPTION
    在js中使用createElement创建HTML对象和元素
    清空select标签中option选项的3种不同方式
    json-lib包笔记
    异常:javax.el.PropertyNotFoundException: Property 'id' not found on ..........
    golang struct的使用
    golang多维数组的切片
  • 原文地址:https://www.cnblogs.com/zaking/p/8686676.html
Copyright © 2020-2023  润新知