JavaScript中的数组

阅读 1.6k
标签: JavaScript

数组在JavaScript中是非常重要且常用的数据结构,本篇将揭露它的一些特性,只有更好的了解它,才能更好的使用它,不是吗?

删除的陷阱

数组是一个对象,可以用delete运算符来从数组中移除元素,如下:

let arr = [1, 3, 5, 7]
delete arr[2]
console.log(arr)

但是这种方式,会导致数组中将留下一个空洞,对于上面的例子来说,数组中的第三项(数字5)被删除,数组长度依旧是4,其他项的索引不变。

有点占着茅坑不拉shi的感觉,这常常不是我们想要的结果。所以删除更多是用splice()方法来做:

// 根据索引curId,删除list中的项
let curId = 2
let list = [
  {id: 1, name: 'a'},
  {id: 2, name: 'b'},
  {id: 3, name: 'c'},
  {id: 4, name: 'd'}
]

list.forEach((v, index) => {
  if (v.id === curId) {
    list.splice(index, 1)
  }
})

上面代码将删除id为2的对象,删除后,数组将只有3个元素。看上去没有什么问题,但如果list中有二个一样的项(且相邻)呢?如下:

let list = [
  {id: 1, name: 'a'},
  {id: 2, name: 'b'},
  {id: 2, name: 'b2'},
  {id: 3, name: 'c'},
  {id: 4, name: 'd'}
]

你会发现,name为b2的项却删除不掉,这是为什么呢?因为forEach遍历删除第一项{id: 2, name: 'b'}后,此时index为2,而这时数组也实时改变了,这时的数组的第三项(index等于2)为{id: 3, name: 'c'},而{id: 2, name: 'b2'}则被跳过了,没有遍历到!这种情况,要用for循环来做,如下:

for (let i = 0; i < list.length; i++) {
  if (list[i].id === curId) {
    list.splice(i, 1)
    i--
  }
}

当删除一项,得将索引减1,这样才能正确遍历每一项。

完了吗?还没!上述问题除了用删除来做,其实有更简单的方法:过滤

list = list.filter(v => v.id !== curId)

只需要将id为2的项过滤掉就好了。

强大的map

在数组中,map是一个功能很强大的方法:

let arr = [5, 2, 0]
  .map(v => {
    return v * 2
  })
  .filter(v => {
    return v > 5
  })

console.log(arr) // [ 10 ]

map()方法可以返回一个新的数组,然后进行链式调用。别以为链式调用只有ES6中的Promise才有,ES5的数组中早就有了。

sort的误用

小明是一个新手前端,他写了一个如下的升序排序:

const arr = [ 0, 1, 5, 10, 15, 10, 100, 99, 100 ]
arr.sort((v1, v2) => {
  return v1 > v2
})
console.log(arr)

跑一跑,完全没有问题,看似很正确!但数据再多一点,如下:

const arr = [ 0, 1, 5, 10, 15, 10, -2, -2, 100, 99, 100 ]

就会发现结果已经不对了,排序不能这样写!正确的写法应该是这样:

arr.sort((v1, v2) => {
  return v1 > v2 ? 1 : -1
})

一定要注意,数组排序,比较函数中返回的值是一个整形,而不是boolean类型。

最后编辑于: 2022-03-16

评论(0条)

(必填)
复制成功