# JS数组

# 特点

  • 元素的数据类型可以不同
  • 内存不一定是连续的(对象是随机存储的)
  • 不能通过数字下标,而是通过字符串下标
  • 数组可以有任何key

# 创建数组

  • 新建数组
let arr = [1,2,3]
let arr = new Array(1,2,3)
let arr = new Array(3)     //一个参数表示数组长度

  • 转化数组

split()方法使用指定的分隔符字符串将一个String对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。

let arr = '1,2,3'.split(',')
let arr = '123'.split('')

Array.from()方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

Array.from('123')

  • 伪数组

伪数组的原型链中并没有数组的原型 没有数组公共属性的数组就是伪数组

  • 合并数组

concat()方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变

let a = [1,2,3,4,5];
let b = [6,7,8,9];
console.log(a.concat(b));//[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(a); //[1, 2, 3, 4, 5]
console.log(b); //[6, 7, 8, 9]
  • 截取数组一部分

slice()方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

let arr = [0,1,2,3,4,5,6,7,8];
arr.slice(2); //从第三个元素开始
console.log(arr.slice(2));//[2, 3, 4, 5, 6, 7, 8]
console.log(arr);//[0, 1, 2, 3, 4, 5, 6, 7, 8]
arr.slice(0)   //全部截取

# 删除元素

错误方法 使用delete arr[0]删除元素并未改变数组长度,若数组全部为空称之为稀疏数组 直接修改arr.length会改变数组,出现意外

正确方法

splice()方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。 参数:开始索引、删除元素的位移、插入的新元素

# 查看元素

  • 查看所有属性名
let arr = [1,2,3,4,5]
for(let i in arr){
  console.log(`${i}:${arr[i]}`)
}
Object.keys(arr)

  • 查看数字(字符串)属性名和值
let arr1 = [1,2,3,4,5,6]
for(let i=0;i<arr.length;i++){
  console.log(`${i}:${arr[i]}`)
}
arr.forEach(function(item,index){
  console.log(`${index}:${index}`)
})

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

forEach函数使用for循环访问array的每一项 对每一项调用fn(array[i],i,array)

# forEach函数与for循环的区别:
  • for循环作用域为块级作用域,foreach作用域为函数作用域
  • 在 for 循环中可以使用 continue,break 来控制循环和跳出循环;forEach 则必须将循环全部执行

  • 查看单个属性
let arr = [1,2,3,4,5]
arr[0]
# 索引越界

  • 查看某元素是否在数组

indexOf()方法返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1

arr.indexOf(item)   //存在返回索引,否则返回-1
  • 使用条件查找元素

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined

arr.find(item => item%2 ===0)   //找第一个偶数
  • 使用条件查找元素的索引

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。

arr.findIndex(item => item%2 ===0)    //查找第一个偶数的索引

# 增加元素

  • 在头部加元素
arr.unshift(newItem)   //修改arr,返回新长度
arr.unshift(item1,item2)  //修改arr,返回新长度
  • 在尾部加元素
arr.push(newitem)   //修改arr,返回新长度
arr.push(item1,item2) //修改arr,返回新长度
  • 在中间添加元素
arr.splice(index,0,'x')   //在index处插入'x'
arr.splice(index,0,'x','y')

# 修改元素

  • 反转顺序

reverse()方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

arr.reverse()  //修改原数组
a.split('').reverse().join('')  //字符串倒序

  • 自定义顺序

sort() 方法用原地算法对数组的元素进行排序,并返回数组。

//比较函数
function compare(a, b) {
  if (a < b ) {           // 按某种排序标准进行比较, a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  return 0;
}
如果 compareFunction(a, b) 小于 0 , a 会被排列到 b 之前
如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变
如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前

# 数组变换

  • map

Test1:将数组值变为平方

let arr = [1,2,3,4,5]
arr2.map(item => item*item)

Test2:请使用 arr.map 把 0 变成'周日',把 1 变成'周一',以此类推

let arr = [0,1,2,2,3,3,3,4,4,4,4,6]
arr.map( item => { return { 0: '周日', 1: '周一', 2: '周二', 3: '周三', 4: '周四', 5: '周五',6: '周六'}[item]
})
  • filter

Test3:取数组偶数

let arr = [1,2,3,4,5,6]
arr.filter(item => item %2 ==0 )

  • reduce

Test4:求数组和

let arr = [1,2,3,4,5]
arr.reduce((sum,item)=>{return sum+item},0)

Test5:使用reduce改写map、reduce

let arr = [1,2,3,4,5,6]
arr.reduce((result,item) => {return result.concat(item*item)},[])

arr.reduce((result,item) => {
  if(item % 2 === 1){
    return result
  }else{
    return result.concat(item)
  }
},[])

Test6:数据变换

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:[]})