JS数组

JS中的数组

  • 元素的数据类型可以不同

    1
    2
    // 混合值
    let arr = [ 'Apple', { name: 'John' }, true, function() { alert('hello'); } ];
  • 内存不一定连续,对象是随机存储的

  • 不能通过数字下标,而是字符串下标
  • 数组可以有任何的key

创建数组

  • 新建

    1
    2
    3
    let arr = [1,2,3]
    let arr = new Array(1,2,3) // 数组元素为1,2,3
    let arr = new Array(3) // 数组长度为3
  • 转化

    1
    2
    3
    let arr = '1,2,3'.split(',');
    let arr = '123'.split('');
    Array.from('123');
  • 伪数组

    1
    2
    3
    4
    let divList = document.querySelectorAll('div');  // 这是一个伪数组
    console.dir(divList); // 伪数组的原型链中没有数组的原型

    var divArray = Array.from(divList); // 将伪数组转换成数组
  • 合并两个数组

    1
    arr1.concat(arr2);  // 得到一个新数组,并不会改变arr1和arr2
  • 截取数组的一部分

    1
    2
    arr1.slice(1);  // 从第二个元素开始截取
    arr1.slice(0); // 浅拷贝(复制)一个数组

增加元素

1
2
3
4
5
6
7
8
9
10
11
// 在尾部增加元素
arr.push(newItem) // 修改arr,返回新长度
arr.push(item1, item2) // 修改arr,返回新长度

// 在头部增加元素
arr.unshift(newItem) // 修改arr,返回新长度
arr.unshift(item1, item2) // 修改arr,返回新长度

// 在中间添加元素
arr.splice(index,0,'x') // 在index处,一个元素都不删,再插入'x'
arr.splice(index,0,'a','b','c') // 在index处,一个元素都不删,再插入'a''b''c'

删除数组元素

1
2
3
4
arr.shift()  // 删除头部元素,并返回被删除的元素
arr.pop() // 删除尾部元素,并返回被删除元素
arr.splice(0,3) // 从第一个元素开始,删除3个元素
arr.splice(2,5,666,7777) // 从第三个元素开始,删除5个元素,并添加两个新元素666,7777

修改元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 反转顺序
arr.reverse();

// 将一串字符串倒序
var cc = 'abcde';
cc.split('').reverse().join('');

// 自定义数组顺序
let arr = [1,11,3,56,8,11,4,33,22]
arr.sort(function(a,b) { // [1, 3, 4, 8, 11, 11, 22, 33, 56]
if( a > b ){
return 1 // a>b return 1,从小到大排序
}else if(a===b){
return 0
}else{
return -1
}
})

arr.sort(function(a,b) { // [56, 33, 22, 11, 11, 8, 4, 3, 1]
if( a > b ){
return -1 // a>b return -1,从大到小排序
}else if(a===b){
return 0
}else{
return 1
}
})

// 对象根据某个属性值排序
let arr = [ {name: '小明', score: 60}, {name:'小芳', score: 55}, {name: '小花', score: 69} ];

arr.sort(function(a,b){
if(a.score > b.score) {
return 1
} else if (a.score === b.score) {
return 0
} else {
return -1
}
})
// 简单写法
arr.sort((a,b) => (a.score - b.score))

查找元素

1
2
3
4
5
6
7
// 查找某个元素是否在数组里
arr.indexOf(item) // 存在返回索引,不存在返回-1
arr.includes(item) // 存在返回true,不存在返回false

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

遍历数组

for 语句 & forEach 语句 & for-of 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// for 语句
var arr = [1,2,3,4,5,6,7,8, ,10]
for(var i = 0; i < arr.length; i++){
console.log(arr[i])
if(arr[i] === 5) {
break; // 1 2 3 4
}
}

// forEach 语句
arr.forEach((item, index, arr)=> {
if(item === 5) return;
})

// for-of 语句
var arr = [{name: 'xxx'}, 18, 'joyce'];
for(item of arr) {
console.log(item);
}

小结

  • for和for-of可以使用break跳出循环,forEach无法跳出循环
  • for遍历数组索引,for-of直接访问实际的元素,forEach回调参数更丰富(元素、索引、原数组)都可获取
  • for与for-of在数组中存在空元素时,同样会执行

map 方法 & filter 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
// filter方法
const recordList = [
{name: '餐饮', type: '-', amount: 150},
{name: '住房', type: '-', amount: 2000},
{name: '基金', type: '+', amount: 1800}
]
const targetItem = recordList.filter(item => {
return item.type === '+'
})

// map方法
let names = ["Bilbo", "Gandalf", "Nazgul"];
let lengths = names.map(item => item.length); // 将每个元素转化为它的字符串长度

小结

  • 两种方法都是生成一个新数组,并不会改变原数组
  • map 会将回调函数的返回值组成一个新数组,数组长度与原数组一致,并且生成的新数组元素是可自定义
  • filter 会将符合回调函数条件的元素组成一个新数组,生成的新数组元素不可自定义,与对应原数组元素一致

some 方法 & every 方法

1
2
3
4
5
6
7
8
// some 方法
var arr = [1,2,3,4,5]
var result = arr.some(function(item,index)=> {
return item > 3 // true
})

// every 方法
[12, 15, 7, ,50, 101].every(x => x >= 10); // false

小结

  • 两种方法都用来做条件判断,都返回一个布尔值
  • some若某一元素满足,就返回true并中断循环。所有元素不满足条件,才返回false
  • every则相反,若有一个元素不满足条件,就返回false并中断循环。若所有元素满足条件,则返回true

reduce 方法 & reduceRight 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var arr1 = [1,4,6,9]
arr1.reduce((result,item) => {
return result.concat(item * item); // [1, 16, 36, 81]
},[])

var arr2 = [1,2,3,4,5,6,7,8,9];
arr2.reduce( (result,item) => {
if (item % 2 === 1){
return result.concat(item); // 奇数就留下
} else {
return result // 不是奇数就返回之前的结果
}
},[])

// 简便写法
arr2.reduce((result,item) =>
(result.concat(item % 2 === 1 ? item : [])) // [1,3,5,7,9]
,[])

小结

  1. reduce方法接受两个参数,第一个参数是回调函数,第二个参数是初始值
  2. reduceRight 方法除了与reduce执行方向相反外,其他完全一致
  3. 回调函数接受四个参数:
    • previousValue:之前所有的数组元素被回调函数处理累计的结果(前一次调用回调函数得到的返回值)
    • currentValue:当前被执行的数组元素
    • currentIndex: 当前被执行的数组元素索引
    • array:原数组,也就是调用 reduce 方法的数组(被遍历的对象)
  4. 如果不传入初始值,reduce 方法会从索引 1 开始执行回调函数,如果传入初始值,将从索引 0 开始、并从初始值的基础上累计执行回调。

25个你不得不知道的数组reduce高级用法

find 方法 & findIndex 方法

1
2
3
4
5
6
7
// find 方法
const arr = [5, 8, 12, 33, 150]
const found = arr.find(item => item > 10) // 12

// findIndex 方法
const arr = [5, 8, 12, 33, 150]
const found = arr.findIndex(item => item > 50) // 4

小结

  • 两者都是用来查找数组元素
  • find方法返回数组中满足callback函数的第一个元素的值,若不存在返回undefined
  • findIndex方法返回数组中满足条件的元素的索引值,若不存在返回-1

习题

  1. 将数字变成星期

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

    console.log(arr2) // ['周日', '周一', '周二', '周二', '周三', '周三', '周三', '周四', '周四', '周四', '周四','周六']
  2. 找出大于60的数字

    1
    2
    3
    let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
    let scores2 = scores.filter( item => item > 60 )
    console.log(scores2) // [95,91,82,72,85,67,66, 91]
  3. 算出所有奇数之和

    1
    2
    3
    4
    5
    let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
    let sum = scores.reduce((sum, n)=>{
    return ( n%2 === 1) ? sum+n : sum
    },0)
    console.log(sum) // 奇数之和:598
  4. 将数组变成对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    let arr = [
    { 名称:'动物', id: 1, parent: null},
    { 名称:'狗', id: 2, parent: 1},
    { 名称:'猫', id: 3, parent: 1}
    ]

    将上面的数组变成对象
    {
    id: 1, 名称: '动物', children: [
    {id: 2, 名称:'狗', children: null},
    {id: 3, 名称:'猫', children: null},
    ]
    }

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