Javascript数组的增删改查和变换操作

485 阅读5分钟

最近在学习Javascript数组的内容,因为数组在编程中非常常用,是一个很重要的知识点,JS中的数组也和之前学习过的JAVA中的数组有一定的区别,所以写下了这篇博客,用来记录JS数组相关的知识,便于自己查阅和复习。

JS数组和典型数组的区别

典型数组

  • 元素数据类型相同
  • 使用连续的内存存储
  • 通过数字下标获取元素

JS数组

  • 元素数据类型可以不同
  • 内存不一定连续(随机存储)
  • 不能通过数字下标(因为JS的对象没有数字下标),而是通过字符串下标
  • 这就意味着数组可以有任何的key
let arr = [1,2,3]
arr['xxx'] = 1

为什么一开始数组有三个元素分别为1,2,3,length为3,后来又添加了一个下标为'xxx'字符串,值为4的元素,length还是3呢?

MDN上是这样描述的:

如果你在以上代码中给数组操作符的是一个非整形数值,那么将作为一个代表数组的对象的属性(property)创建,而非作为数组的元素。

var arr = [];
arr[3.4] = "Oranges";
console.log(arr.length);                // 0
console.log(arr.hasOwnProperty(3.4));   // true

所以当我们试图为JavaScript的数组添加非整形数值字符串下标的时候,其实相当于为该数组对象添加了一个自有属性property,而不是增加了一个数组元素。由于数组对象添加属性不会影响到length的值,所以length并没有发生变化。同样的数组的pop和shift等方法也不能作用于这些属性身上。

另外,当我们给数组添加整型数组字符串下标时,会把字符串转换成整型数字作为下标。

我们想像添加非整型数值字符串一样把'101'当成数组的自有属性存储,结果整型字符串'101'却被强行转换成整型数字,当作数组元素存放了。


创建数组

新建

  • let arr=[1,2,3] //简单写法
  • let arr=new Array(1,2,3) //标准写法
  • let arr=new Array(3) //长度为3的空数组,而不是长度为1,值为3的数组

转化

  • let arr='1,2,3'.split(',') //以','为分隔符将字符串转化为数组
  • let arr='123'.split('') //以空字符为分隔符将字符串转化为数组
  • Array.from('123') //将一个类数组对象或者可遍历对象转换成一个真正的数组

合并

  • arr1.concat(arr2) //合并两个数组得到新数组

截取

截取一个数组的一部分得到一个新数组

  • arr1.slice(1) //从第二个元素开始
  • arr2.slice(0) //全部截取

伪数组

let divList=document.querySelectorAll('div')

伪数组有数组的length属性,原型链中却没有数组的原型

数组元素的删除

delete

delete arr['0']只删除下标0对应的值,置为empty,下标0依然存在,数组的length不变。如果数组中的数值全部用delete删除,则变成稀疏数组。

length

直接设置arr.length值可以把数组截断,只保留前${length}个元素,但不建议这样使用。

shift

删除头部的元素,并返回被删除的元素。

arr.shift()

pop

删除尾部的元素,并返回被删除的元素。

arr.pop()

splice

可以实现删除元素,添加元素或者替换元素。

arr.splice(index,1) //index为开始删除的下标,后面的数字为想删除的个数
arr.splice(index,1,'x')  //在删除的地方添加'x',相当于把这个元素替换成了'x'
arr.splice(index,1,'x','y') //在index下标开始删除一个元素并添加'x''y'
arr.splice(2)  //从下标为2的地方开始删除后面所有元素
arr.splice(2,0,'x') //从下标为2的地方开始删除0个元素,增加一个'x'元素,这个元素加在下标2的前面
arr.splice(-2,1) //从数组索引最末端开始往前数的第二个下标开始删除1个元素

查看所有元素

查看所有属性名

let arr=[1,2,3,4,5]
arr.x='xxx'
Object.keys(arr)
for(let key in arr){
	console.log(`${key}:${arr[key]}`)
}  //这是遍历对象属性的方法,如果是要遍历数组则不是很建议使用,如果数组里有property,会输出property的值,和预期结果不符

查看数字(字符串)属性名和值

for(let i==0;i<arr.length;i++){
	console.log(`${i}:${arr[i]}`)
}//可以提前break
arr.forEach(function(item,index){
	console.log(`${index}:${item}`)
})//不能break

手写Array.forEach()

    function forEach(array,fn){
        for(let i=0;i<array.length;i++){
            fn(array[i],i,array)
        }
    }

查看单个属性

查找某个元素是否在数组里

arr.indexOf(item) 存在返回索引,不存在返回-1。

使用条件查找元素

arr.find(item=>item%2===0)找第一个偶数。

使用条件查找元素的索引

arr.findIndex(item=>item%2===0)

增加数组中的元素

在尾部加元素

arr.push(newItem)

arr.push(item1,item2)

在头部加元素

arr.unshift(newItem)

arr.unshift(item1,item2)

在中间添加元素

arr.splice(index,0,'x')

arr.splice(index,0,'x','y')

修改数组中的元素

反转顺序

arr.reverse()

例:var a=[1,2,3,4,5]
    a.reverse()
    console.log(a) //[5,4,3,2,1]

自定义顺序

arr.sort([compareFunction(first,second)])

compareFunction是用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行升序排序(给数组[3,2,1,4,10]排序会变成[1,10,2,3,4],10的unicode码比2小),返回值是原数组,不生成新的数组。 如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
function compare(a, b) {
  if (a < b ) {           // 升序排序
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}
---------------------------------------------------
function compare(a, b) {
  if (a < b ) {           // 降序排序
    return 1;
  }
  if (a > b ) {
    return -1;
  }
  // a must be equal to b
  return 0;
}

数组变换

map(n变n)

map 方法会迭代数组中的每一个元素,并根据回调函数来处理每一个元素,最后返回一个新数组。注意,这个方法不会改变原始数组。

var oldArray= [1,2,3,4,5]
var newArray = oldArray.map(function(data){
	return data+3
})//数组每个元素加三

filter(n变少)

filter方法用来迭代一个数组,并且按给出的条件过滤出符合的元素。filter 方法传入一个回调函数,这个回调函数会携带一个参数,参数为当前迭代的项(我们叫它 val )。回调函数返回 true 的项会保留在数组中,返回 false 的项会被过滤出数组。

var oldArray = [1,2,3,4,5,6,7,8,9,10]
var newArray = oldArray.filter(function(val){
	return val<6
})//从数组中选出小于6的元素

reduce(n变1)

数组方法 reduce 用来迭代一个数组,并且把它累积到一个值中。reduce需要传入两个参数,用来代表数组中的值,reduce 方法有一个可选的第二参数,它可以被用来设置累加器的初始值。如果没有在这定义初始值,那么初始值将变成数组中的第一项,而第二个参数 将表示从数组的第二项开始。

var array = [4,5,6,7,8]
var singleVal = 0
singleVal = array.reduce(function(first,second){
	return first+second;
},0)//计算数组所有元素的总和

题目:用reduce将数组变成对象

39512a2edf8b4ee937b6c2057657efe.png

原数组结构:

cf010533cc98f46c37416d6474f4b9d.png

  arr.reduce((result,item)=>{
      if(item.parent===null){
          result.id=item.id
          result['名称']=item['名称']
      }else{
          result.children.push(item)
          delete item.parent
          item.children=null
      }
      return result
  }
  ,{id:null,children:[]})

输出结果:

d248ccfa2f70d492db3257637af459e.png