js数据结构与算法学习(一)——数组

·  阅读 69

1.数组存放数据类型

  • 最好存放同一数据类型的值
  • 可以更简洁展现同样的信息

2.访问数组/迭代数组的操作

示例2-1: 求斐波那楔数列的前20个数?

let arr = [];
arr[1] = 1;
arr[2] = 2;
for (let i = 3; i < 21; i++) {
  arr.push(arr[i - 1] + arr[i - 2]);
}
arr.shift();
console.log(arr); // =>[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,]

复制代码

3. 对数组元素的操作

  • 示例数组
let caseArr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
复制代码

3.1 在数组尾部插入元素

  1. 使用数组的长度
// js数组索引是从0开始
caseArr[caseArr.length] = 10;
console.log(caseArr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
复制代码
  1. js的push方法
caseArr.push(10);
caseArr.push(11, 12, 13);
console.log(caseArr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
复制代码

3.2 在数组开头插入元素

  1. 使用迭代的方式
Array.prototype.addFirstEle = function (value) {
  for (let i = this.length; i > 0; i--) {
    this[i] = this[i - 1];
  }
  this[0] = value;
};

caseArr.addFirstEle(0);
console.log(caseArr);//[0,1, 2, 3, 4, 5, 6, 7, 8, 9]
复制代码
  1. js的unshift方法
caseArr.unshift(0);
console.log(caseArr); //[0,1, 2, 3, 4, 5, 6, 7, 8, 9]
caseArr.unshift(-2,-1);
console.log(caseArr);//[-2, -1,0,1, 2, 3, 4, 5, 6, 7, 8, 9]
复制代码

3.3 删除数组尾部元素

  • js方法之pop
let caseArr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
caseArr.pop()
console.log(caseArr);//[1, 2, 3, 4, 5, 6, 7, 8]
复制代码

3.4 删除数组头部元素

  • js方法之shift
let caseArr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
caseArr.shift()
console.log(caseArr);//[ 2, 3, 4, 5, 6, 7, 8,9]
复制代码

3.5 任意位置添加删除元素

  • 使用js数组的splice方法
let caseArr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

// 删除元素操作
caseArr.splice(2, 3); // 删除了从数组索引2开始的3个数组元素
console.log(caseArr); // [ 1, 2, 6, 7, 8, 9 ]
复制代码
let caseArr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

// 添加元素操作
caseArr.splice(2,0,10,11,12); // 从数组索引2开始,添加10, 11, 12,
console.log(caseArr); // [1, 2, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9]
复制代码

4. 聊聊多维数组w

4.1 先来看一个二维的数组

// 我是二维数组
let twoArr = [
  [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],
];
复制代码
  • 看到上面数组,让人想起了矩阵
  • 不需要怀疑,就是矩阵(数学上);
  • 在js中我们还是称之为数组;
  • js不认识矩阵,只认识一维数组,姑且叫它数组的数组吧;

二维数组.png

4.1.1 迭代一个二维数组
  • 我们来输出4.1中的二维数组
// 我是二维数组
let twoArr = [
  [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],
];

printTwoArr(twoArr);
function printTwoArr(arr) {
  const leng = arr.length;

  // i表示数组的行
  for (let i = 0; i < leng; i++) {
    let iLeng = arr[i].length;

    // j 表示数组的列
    for (let j = 0; j < iLeng; j++) {
      console.log(arr[i][j]);
    }
  }
}

/* 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*/
复制代码

建议:使用console.table(arr),可在浏览器控制台打印更加易读的二维数组;

image.png

4.2 多维数组

  • 4.1中可知二维数组使用两个嵌套的for循环来访问;
  • 那么我们可不可以用3层for循环来访问三维数组及更多层的for循环访问更多层的数组呢?
4.2.1 创建三维数组
let matrix3x3x3 = [];

for (let i = 0; i < 3; i++) {
  matrix3x3x3[i] = [];
  for (let j = 0; j < 3; j++) {
    matrix3x3x3[i][j] = [];
    for (let z = 0; z < 3; z++) {
      matrix3x3x3[i][j][z] = i + j + z;
    }
  }
}
console.log(matrix3x3x3); // 打印结果如下
/* [
  [
    [0, 1, 2],
    [1, 2, 3],
    [2, 3, 4],
  ],
  [
    [1, 2, 3],
    [2, 3, 4],
    [3, 4, 5],
  ],
  [
    [2, 3, 4],
    [3, 4, 5],
    [4, 5, 6],
  ],
]; */
复制代码
4.2.2 迭代三维数组
printMatrix3x3x3(matrix3x3x3);
function printMatrix3x3x3(arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      for (let z = 0; z < arr[i][j].length; z++) {
        console.log(arr[i][j][z]);
      }
    }
  }
}
复制代码
  • 到这里就发现规律了,更多维的数组,以此类推;

5. js中的一些数组方法使用

5.1 合并数组

背景:多个数组何为一个数组。

  • 采用js的concat方法
let ele = 0;
let objItem = { name: "lisi" };
let leftArr = [1, 2, 3];
let RightArr = [4, 5, 6];

// 把元素合并到数组中
console.log(leftArr.concat(ele)); // [ 1, 2, 3, 0 ]

// 把对象合并到数组中
console.log(leftArr.concat(objItem)); // [ 1, 2, 3, { name: 'lisi' } ]

// 把其中一个或多个数组合并到另一个数组中
console.log(leftArr.concat(ele,objItem,RightArr)); // [ 1, 2, 3, 0, { name: 'lisi' }, 4, 5, 6 ]
复制代码

5.2 数组的迭代方法

  • 声明一个数组
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15];
复制代码
5.2.1 every方法
  • 可以迭代数组中的元素,直到返回false,执行结束。
arr.every((v, i, arr) => {
  console.log(v); // 1
  return v % 2 === 0 ? true : false;
});
复制代码
5.2.2 some方法
  • 可以迭代数组中的元素,直到返回true,执行结束。与every行为正好相反
arr.some((v, i, arr) => {
  console.log(v); // 2
  return v % 2 === 0 ? true : false;
});
复制代码
5.2.3 forEach方法
  • 可以迭代数组中的每个元素。
arr.forEach((v,i,arr)=>{
    console.log(v);
})
复制代码
5.2.4 mapfilter方法
  • map可以映射数组中的每个元素,返回一个新数组
const mapArr = arr.map((v, i, arr) => {
  return v + 10;
});
console.log(mapArr); //[11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25];
复制代码
  • filter可以过滤数组中的每个元素,返回符合过滤条件的一个新数组
const filterArr = arr.filter((v, i, arr) => {
  return v > 5;
});
console.log(filterArr); // [6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
复制代码
5.2.5 reduce方法
  • 可以迭代数组中的每个元素。
console.log(
  arr.reduce((previousValue, currentValue, currentIndex, array) => {
    return previousValue + currentValue;
  })
);  // 120
复制代码

5.3 es6和数组的新功能

5.3.1 使用for...of循环迭代
  • 可以用来迭代数组,并从数组实例中得到迭代器对象
for (const v of arr) {
  console.log(v % 2 === 0 ? "even" : "odd");
}
复制代码
5.3.2 使用 @@iterator 对象
  • 赶回一个包含数组键值对的迭代器对象,可以通过同步调用得到数组元素的键值对;
  • es6为Array类增加了一个@@iterator属性,通过Symbol.iterator访问
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

let iterator = arr[Symbol.iterator]();

console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
console.log(iterator.next().value); // 4
console.log(iterator.next().value); // 5


for (const v of iterator) {
    console.log(v);
}
复制代码
5.3.3 数组的 entries、keys、values方法
  • es6特性
  • 他们能从数组中得到迭代器
  1. entries返回包含键值对的 @@iterator
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

let entriesiterator = arr.entries(); // 得到键值对的迭代器

console.log(entriesiterator.next().value); // [ 0, 1 ]- 位置0的值为1
console.log(entriesiterator.next().value); // [ 1, 2 ]- 位置1的值为2
console.log(entriesiterator.next().value); // [ 2, 3 ]- 位置2的值为3

for (const v of entriesiterator) {
  console.log(v);
}
复制代码
  1. keys方法返回包含数组索引的 @@iterator
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

let keysiterator = arr.keys();  // 得到数组索引的迭代器

console.log(keysiterator.next()); // { value: 0, done: false }
console.log(keysiterator.next()); // { value: 1, done: false }
console.log(keysiterator.next()); // { value: 2, done: false }
复制代码
  • keys方法返回数组索引。若没有可迭代的值,keysiterator.next()会返回一个{value:undefined,done:true}的对象
  1. values方法返回 @@iterator 包含数组的值
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

let valuesiterator = arr.values(); 

console.log(valuesiterator.next()); // { value: 1, done: false }
console.log(valuesiterator.next()); // { value: 2, done: false }
console.log(valuesiterator.next()); // { value: 3, done: false }
复制代码
5.3.4 使用 Array.from
  • 根据已有的数组创建一个新数组
let newArr = Array.from(arr);

// 传入一个函数过滤值
let newArr = Array.from(arr,(v)=>v>10);
复制代码
5.3.5 使用 copyWithin 方法
  • 复制数组中的一系列元素待同意数组指定的起始位置
let arr = [1, 2, 3, 4, 5, 6];

console.log(arr.copyWithin(0,3)); // [ 4, 5, 6, 4, 5, 6 ]

// 把从位置3开始到位置5结束(不包含位置5)的元素复制到位置1
console.log(arr.copyWithin(1,3,5)); // [ 1, 4, 5, 4, 5, 6 ]
复制代码

5.4 数组排序

  • reverse方法:使数组反序输出
let arr = [1, 2, 3, 4, 5, 6];
arr.reverse();
console.log(arr); // [ 6, 5, 4, 3, 2, 1 ]
复制代码
  • sort方法:在对数组排序时,把元素默认成字符串进行相互比较
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.reverse();
arr.sort();
console.log(arr); // [1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
复制代码

可以自己写比较函数。

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.reverse();
arr.sort((a, b) => a - b);
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
复制代码
  • 自定义排序
let arr = [
  { name: "qianxue", age: 19 },
  { name: "lisi", age: 18 },
  { name: "zhangsan", age: 20 },
];

arr.sort((a, b) => {
  return a.age - b.age;
});

console.log(arr);
/* [
  { name: "lisi", age: 18 },
  { name: "qianxue", age: 19 },
  { name: "zhangsan", age: 20 },
]; */
复制代码

5.5 数组搜索

5.5.1 indexOf
  • 返回与参数匹配的第一个元素的索引;
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

console.log(arr.indexOf(10)); // 9
console.log(arr.indexOf(100)); // -1 表示不存在
复制代码
5.5.2 lastIndexOf
  • 返回与参数匹配的最后一个元素的索引;
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,10];

console.log(arr.lastIndexOf(10)); // 15
console.log(arr.lastIndexOf(100)); // -1 表示不存在
复制代码
5.5.3 es6 —— find和findIndex
  • find和findIndex,搜索一个满足回调函数条件的值
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10];

console.log(
  arr.find((v, i, arr) => {
    return v % 13 === 0;
  })
); // 13
console.log(
  arr.findIndex((v, i, arr) => {
    return v % 13 === 0;
  })
); // 12
复制代码

find和findIndex的区别:find返回第一个满足条件的值,findIndex返回这个值在数组中的索引。如果没有满足条件的值,find返回undefined,findIndex返回-1。

5.5.4 es7 —— includes方法
  • 数组中存在某个元素,includes方法返回true,否则返回false。
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10];

console.log(arr.includes(15)); // true
console.log(arr.includes(20)); // false
复制代码
  • includes方法传入一个索引(第二个参数),搜索会从索引指定的位置开始
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10];

console.log(arr.includes(5,6)); // falsejs
复制代码

5.6 数组变为字符串

  • toString():把数组所有元素输出为一个字符串
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10];

console.log(arr.toString()); // 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10
复制代码
  • join():把数组输出为一个字符串
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10];

console.log(arr.join('-')); // 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-10
console.log(arr.join('')); // 12345678910111213141510
复制代码
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改