对js数组及其方法的理解

本文详细介绍了JavaScript中数组的常用方法,如sort()的排序规则、splice()的添加删除操作、slice()的切片功能、join()的连接字符串以及深浅拷贝的区别。同时涵盖了去重、findIndex方法和数组遍历的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组常用方法:

改变原数组

Push/pop/unshift/shift

末尾添加/删除、头部添加/删除

reverse

颠倒

sort

排序

splice(开始,删除数,添加元素)

指定位置《前》添加或删除元素

不改变原数组

includes

数组是否包含指定值

indexOf、lastIndexOf

判断指定字符首次、最后一次出现的位置

slice

截取

concat

拼接

join

元素变字符串

下面说些不那么容易理解的或使用变化多的方法:

sort方法

首先sort是数组的一个方法,sort() 方法用于对数组的元素进行排序!然后返回排序后的数组。默认排序顺序是升序,建立在将元素转换为字符串,然后比较其UTF-16(一种编码格式)代码单元值的序列的基础上,请注意,该数组按位置排序,并且不进行任何复制!

1.默认无参数(升序)

可以验证下上面的是否正确:

      let arr = [43, 2, 2, 5, 6];
      arr.sort();
      console.log(arr);

2.有参数(应该是个排序规则的函数)

传入的函数给定一对特定的元素a ,b 作为其两个参数,sort函数有return返回值,如果返回值大于0就是升序排列,如果是小于0就是降序!等于0就顺序不变

a=b  保持原来位置不变

a>b  升序

a<b  降序

sort总结:

以下我自己的理解(不一定对仅个人观点):

1.sort函数是降序还是 升序完全是由排序函数决定。

2.若  return后的数 

         > 0   整体升序      

        <  0    整体降序

        =  0    保持位置不变

3.如果你要排序的是数组内部是  数值 那使用参数 a,b 你就可以认为a>b(a-b>0,return a-b自然就升序 ,以下例子证明我的观点

例子1:
var asc = (a,b)=>a-b;  //升序
var des= (a,b)=>b-a;   //降序
var arr = [10, 44, 5, 78, 1, 99];
var arr1 = [10, 44, 5, 78, 1, 99];
console.log(arr.sort(asc));// [1, 5, 10, 44, 78, 99]
console.log(arr1.sort(des))// [99, 78, 44, 10, 5, 1]

例子2:
var asc = (a, b) => a - b < 0 ? -1 : 1 //升序
var des = (a, b) => a - b < 0 ? 1 : -1 //降低序
var arr = [10, 44, 5, 78, 1, 99];
var arr1 = [10, 44, 5, 78, 1, 99];
console.log(arr.sort(asc));// [1, 5, 10, 44, 78, 99]
console.log(arr1.sort(des))// [99, 78, 44, 10, 5, 1]

4.如果你要排序的是数组内部是  字符串  将a,b看作数组内任意两个字符串且a不等于b,根据各种条件去控制调整字符串的顺序。 以下是我项目中的例子单独提出来了:

splice()方法

作用:数组的指定位置 《前》 添加或删除元素

特点:会改变原数组

参数

描述

index

必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

howmany

必需。要删除的项目数量。如果设置为 0,则不会删除项目。

item1, ..., itemX

可选。向数组添加的新项目。

let arr = [1, 2, 4]
arr.splice(1, 0, 23, 345)   //[1,23,345,2,4]
arr.splice(1,1)             //[1,345,2,4]

arr.splice(0)               //[]   清空数组

slice()方法

作用:截取数组的返回新数组,就俩参数开始的位置start,结束的位置end

let arr1 = [1, 435, 546, 7]
arr1.slice(1,3)   //[435,546]
arr1.slice(-2)    //[546,7]
arr1.slice(1,-1)  //[435,546]
arr1.slice()      //[1, 435, 546, 7]  //可以用来拷贝数组-并且是深拷贝

隐藏做用 ---- 拷贝数组

join()方法

作用:   数组元素变字符串

let arr1 = [1, 435, 546, 7]
arr1.join());       //1,435,546,7
arr1.join("");      //14355467
arr1.join(" ");     //1 435 546 7
arr1.join("-");     //1-435-546-7

数组的深浅拷贝

写项目的时候,有时候稍不注意这个深浅拷贝就可能造成意想不到的bug,解决那对于新手来说很麻烦如果不知道问题出在哪里。

我理解的深浅拷贝:

浅拷贝:只是复制指针给另外一个变量,实际上他俩指向的是同一个地址

深拷贝:复制数组(这里先认为是数组)内的值 到另外一个地址 

我们都知道js中 数组作为复杂数据类型 ,它使用赋值符号  去把它赋值给另一个变量是浅拷贝 ,  只是将 数组的指针(地址)赋值给了新变量。其实新变量指向的还是这个数组。

如果你使用 tenpArr 进行数组操作修改了数组内的值,自然arr也会变化,因为它俩指向的是同一个数组啊。

数组中常见的深浅拷贝的操作:

说明一下,在js中深浅拷贝只针对复杂数据类型的,像 number bool undefined null string 等

不存在深浅拷贝的问题 。 string说明下:String其实是引用类型,只是编译器对其做了特殊处理(使其和基本数据类型一样)。  当然js中使用话就把他当作基本数据类型就行。

浅拷贝:

1.赋值符号  =

2.Object.assign()

深拷贝:

  1. JSON.parse(JSON.stringify(arr))

即可是深拷贝也可是浅拷贝

注意:下列拷贝时既可以是深拷贝也可以是浅拷贝,取决于内部元素数据类型

  1. slice(0)
  2. [...arry]
  3. arr.concat()
  4. 当然还包括for循环...遍历方式将数组内的值挨个拷贝到另一个数组中

这里说下注意点:我们知道数组遍历/过滤方法有些能返回新数组,那这些新数组就是  (新的)

实现深拷贝,比如

 let newarrarr.filter((val,index)=>{

            return val.name.includes("")

        })

newarr 这数组和原来数组没任何关系,这个也可以实现深拷贝

举例:

eg1:使用扩展运算符 ... 进行数组拷贝时,无论是原始值类型还是对象,拷贝的都是值的引用。对于原始值类型,修改拷贝后的数组不会影响原始数组,因为它们是独立的值。而对于对象,修改拷贝后的数组中的对象会影响原始数组中的对象,因为它们共享同一个引用。

let originalArray = [{ a: 1 }, { b: 2 }];
let copiedArray = [...originalArray];
originalArray[0].a = 10;
console.log(copiedArray); // 输出: [{ a: 10 }, { b: 2 }]

let arr = [1, 3, 345, 546, 6];
let arr2 = [...arr];
arr2[1] = 234;
console.log("arr", arr);  // 输出: arr [1, 3, 345, 546, 6]
console.log("arr2", arr2); // 输出: arr2 [1, 234, 345, 546, 6]

eg2:

//1.数组内元素为复杂数据类型
let arr = [{
    tag0_description: ["一级算法Plat64,二级算法OVCrossTalk_32C,ov_crosstalk_32c_fullsize 模式校准数据;"]}];
let ary = [],ary1 = [];
ary = arr.slice(0);
arr[0].tag0_description[0] = "23432";

console.log(ary);//  [{"tag0_description": ["23432"]}]

//2.数组内元素为简单数据类型
let arr1 = [0, "23", true];
ary1 = arr1.slice(0);
arr1[0] = "23432";

console.log(ary1);//[0,"23",true]

数组去重

很多方法包括循环遍历、递归等等我这里分享下感觉比较简单的(一维数组去重

var arr = [1,2,2,3,3,4,4,5,5]

function dedupe(array) {

     return [...new Set(array)]

 }

console.log(dedupe(arr))

//简化代码:

[...new Set(array)]         //细心的可能发现了这其实也实现了深拷贝

注意:

对于数组去重的效率问题检测

数据量1w:set这种方法效率很高,在底层是c源码实现。

数据量百万千万wfor循环结合对象属性的唯一性效率更高

Indexof()在大量的数据处理过程中会极大的降低代码性能,所以在大量数据处理的代码中,我们应该避免使用它。

数组遍历

findIndex()方法

作用:方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1

这个方法前两天遇到了,看起来和find方法很像但是还是有区别的,感觉特定情况下非常好用。

find方法为数组中每个元素执行一次callback函数,直到有一个callback返回true,返回这个元素

而findIndex是返回符合条件的第一个索引

下面是项目实例:

 function func() {
        let content = [
          ["0x0", "2", "0xf", "HL"],
          ["0x2", "1", "0x01", "L"],
          ["0x3", "4", "0xff", "4Byte_L_H"],
          ["0x7", "12", "0x02", "array"],
          ["0x13", "1", "0x01", "L"],
        ];
        let BurnModel = "";
        //大端模式数组
        const RuleArryHL = ["4Byte_H_L","Float_4Byte_H_L","double_8byte_h_l","HL"];
        //小端模式数组
        const RuleArryLH = ["4Byte_L_H","Float_4Byte_L_H","double_8byte_l_h","LH"];

        if (content.length > 0) {
          // 遍历content数组,找到满足条件的元素
          const tempIndex = content.findIndex((element, index) => {
            // 如果BurnModel存在
            if (BurnModel) {
              // 如果BurnModel为"HeightLow"
              if (BurnModel === "HeightLow") {
                // 判断element是否包含RuleArryLH中的元素
                return RuleArryLH.some((rule) => element.includes(rule));
                // 如果BurnModel为"LowHeight"
              } else if (BurnModel === "LowHeight") {
                // 判断element是否包含RuleArryHL中的元素
                return RuleArryHL.some((rule) => element.includes(rule));
              }
              // 如果BurnModel不存在
            } else {
              // 如果RuleArryHL中的元素包含element
              if (RuleArryHL.some((rule) => element.includes(rule))) {
                BurnModel = "HeightLow";
                // 如果RuleArryLH中的元素包含element
              } else if (RuleArryLH.some((rule) => element.includes(rule))) {
                BurnModel = "LowHeight";
              }
            }
            // 返回false
            return false;
          });

          // 如果找到满足条件的元素
          if (tempIndex !== -1) {
            BurnModel = "mixModel";
          }
        }

        console.log("BurnModel:", BurnModel);
      }
      func();

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值