重读《学习JavaScript数据结构与算法-第三版》- 第3章 数组(一)

定场诗

大将生来胆气豪,腰横秋水雁翎刀。
风吹鼍鼓山河动,电闪旌旗日月高。
天上麒麟原有种,穴中蝼蚁岂能逃。
太平待诏归来日,朕与先生解战袍。

此处应该有掌声...

前言

读《学习JavaScript数据结构与算法》- 第3章 数组,本节将为各位小伙伴分享数组的相关知识:概念、创建方式、常见方法以及ES6数组的新功能。

数组

数组是最简单的内存数据结构,用于存储一系列同一种数据类型的值。

注:虽然数组支持存储不同类型的值,但建议遵守最佳实践。

一、数组基础

创建和初始化数组

  1. new Array()

    // 空数组
    let heros = new Array()
    // 指定长度的数组 - 默认每个索引位置的值为undefined
    heros = new Array(7)
    // 直接将数组元素以参数的形式传入数组构造器
    heros = new Array('钟馗', '张良', '虞姬', '亚瑟', '荆轲')
    
  2. 字面量语法:[]

    	let heros = ['鲁班', '吕布', '王昭君', '蔡文姬', '孙悟空']
    

    推荐使用[]定义数组

数组索引

  • 数组的索引从0开始,依次累加;
  • 数组索引的最大值为数组的长度-1;
  • 每个数组的值都对应了一个数组的索引。

索引亦可称之为下标或键

数组长度

数组的.length属性可获取元素的长度

let heros = ['鲁班', '吕布', '王昭君', '蔡文姬', '孙悟空']
console.log('数组students的长度为:' + heros.length)

数组取值

使用 数组名[索引]的形式获取数组的值

let heros = ['凯', '兰陵王', '瑶', '云中君', '典韦']
console.log('第一位英雄:' + heros[0]) // 凯

迭代数组

此处我们使用高大上的名词迭代,拒绝低调的遍历,不要问我为什么!

数组的迭代我们可以选择最简单的循环结构

for (let i = 0; i < heros.length; i++) {
  console.log(heros[i])
}

常见面试题:斐波那契数列

斐波那契数列概念:第一项为1,第二项为1,从第三项开始,值为前两项之和; 如 1, 1, 2, 3, 5, 8, 13 ...

// 求斐波那契数列前20个数
let fibonacci = []
fibonacci[0] = 1
fibonacci[1] = 1

for (let i = 2; i < 20; i++) {
  fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]
}

// 输出
console.log(fibonacci)

二、数组元素操作

添加元素

数组尾部添加元素

  1. 将值赋值在数组的最后一个空位上的元素即可

    	let heros = ['猪八戒', '嫦娥', '孙策']
    	heros[heros.length] = ['苏烈']
    
  2. 使用push方法

    	heros.push('黄忠')
    	console.log(heros) // [ '猪八戒', '嫦娥', '孙策', '黄忠' ]
    

数组开头插入元素

  1. 自定义实现数组开头插入元素的方法

    实现逻辑思考:在数组的开头插入一个元素,需要空出数组第一个元素的位置,将所有的元素都向右移动一位

    	Array.prototype.insertFirstPosition = function (value) {
    	  for (let i = this.length; i >= 0; i--) {
    	    this[i] = this[i - 1]
    	  }
    	  this[0] = value
    	}
    	heros.insertFirstPosition('周瑜')
    	console.log(heros) // [ '周瑜', '猪八戒', '嫦娥', '孙策', '黄忠' ]
    
  2. 使用unshift方法

    	heros.unshift('元歌')
    

    此方法背后的逻辑和insertFirstPosition方法的行为是一样的。

    常见面试问题:

    思考:如果有一个存储了大量数据的数组,在执行插入操作时,将值插入到指定的位置会发生什么情况?

    答:从当前插入值的位置开始,后面所有数组元素都要向右移动一位。

    追问:性能会好吗?

    答:肯定是不好的! 如包含1000个元素的数组,在数组索引0位置插入一个元素,需要移动1000个元素,性能肯定不好

    追问:如何优化呢?

    答:采用JS的链表结构 --- 啥是链表结构呢,请看持续关注公众号文中呦...

删除元素

数组尾部删除元素

heros.pop()

数组开头删除元素

heros.shift()

在任意位置添加或删除元素 -- splice

// array.splice(index[, number][, newValue1][, newValue2...])
// 从指定索引位置开始,执行删除相应数量的元素,并添加执行的元素
let heros = ['周瑜', '猪八戒', '嫦娥', '孙策', '黄忠']
heros.splice(2, 1, '孙悟空')
console.log(heros) //  [ '周瑜', '猪八戒', '孙悟空', '孙策', '黄忠' ]

二维数组与多维数组

// 二维数组
let heros = [
  ['甄姬', '女娲', '安琪拉', '貂蝉'],
  ['典韦', '亚瑟', '曹操', '夏侯惇']
]

// 二维数组取值
console.log(heros[0][1]) // 女娲

// 多维数组
heros = [
  [
    ['甄姬', '安琪拉']
  ],
  [
    ['操作', '夏侯惇']
  ]
]
// 多维数组取值
console.log(heros[0][0][1]) // 安琪拉

无论是几维的数组,只要按照索引去取值就好

三、数组常见方法

在JS中,数组是改进过的对象。这意味着创建的每一个数组都有一些可用的方法。

核心方法一览表

方法描述
concat连接2个或多个数组,返回结果
every对数组中的每个元素运行给定函数,如果该函数对每个元素都返回true,则返回true
filter对数组中的每个元素运行给定函数,返回该函数会返回true的元素组成的数组
forEach对数组中的每个元素运行给定函数,这个方法没有返回值
join将所有的数组元素连接成一个字符串
indexOf返回第一个与给定参数相等的数组元素的索引,没有找到返回-1
lastIndexOf返回数组中搜索到的与给定参数相等的元素的索引里最大的值
map对数组中的每个元素运行给定函数,返回每次函数调用的结果组成的数组
reverse颠倒数组中元素的顺序,反转
reduce接收一个函数作为累加器,返回一个最终计算的值
slice传入索引值,将数组里对应索引范围内的元素作为新数组返回
some对数组中的每个元素运行给定函数,如果任意元素返回true,则返回true
sort按照字母顺序进行排序,支持传入指定排序方法的函数作为参数
toString将数组作为字符串返回
valueOf和toString类似,将数组作为字符串返回

数组合并

concat方法可以向一个数组传递数组、对象或元素,数组会按照该方法传入的参数顺序连接指定的数组

let hz = '黄忠'
let partOfHeros = ['孙悟空', '孙斌', '李白']
let heros = ['钟馗']
let herosList = heros.concat(hz, partOfHeros)
console.log(heroList) // [ '钟馗', '黄忠', '孙悟空', '孙斌', '李白' ]

迭代器函数

一定要说迭代,不要说遍历,不要问我为什么!

every

every会迭代数组中的每个元素,直到返回false

// 判断数组中是否全部是偶数
let arr = [1, 2, 3, 4]
let res = arr.every(v => v % 2 === 0)
conso.e.log(res) // false

some

some会迭代数组中的每个元素,直到返回true

// 判断数组中是否有偶数
let arr = [1, 2, 3]
let res = arr.some(v => v % 2 === 0)
console.log(res) // true

forEach

迭代数组每一个元素

let arr = ['张良', '姜子牙', '露娜', '凯']

map

map会迭代数组的每个元素,对每个元素运行给定的方法,返回每次的结果

// 计算数组元素的乘方结果
let arr = [1, 2, 3]
let newArr = arr.map(v => v ** 2)
console.log(newArr) // [ 1, 4, 9 ]

filter

filter会迭代数组的每个元素,对每个元素运行给定的方法,返回的新数组由返回true的元素组成

// 返回数组中所有的女性英雄
let heros = [
  {
    name: '甄姬',
    sex: '女'
  },
  {
    name: '亚瑟',
    sex: '男'
  },
  {
    name: '貂蝉',
    sex: '女'
  }
]
let nvHeros = heros.filter(hero => hero.sex === '女')
console.log(nvHeros) // [ { name: '甄姬', sex: '女' }, { name: '貂蝉', sex: '女' } ]

reduce

接收一个函数作为累加器,最后返回一个计算的值

// 计算数组元素的和
let arr = [1, 2, 3, 4, 5, 6]
let sum = arr.reduce((previous, current) => previous + current)
console.log(sum) // 21

常见面试题-反转字符串

如字符串 abcdef 输出为 fedcba

  1. 使用for循环倒序拼接

    	let str = 'abcdef'
    	let newStr = ''
    	for (let i = str.length - 1; i >= 0; i--) {
    	  newStr += str[i]
    	}
    	console.log(newStr) // fedcba
    
  2. 借助数组函数reversejoin与字符串函数split

    	let str = 'abcdef'
    	let newStr = str.split('').reverse().join('')
    	console.log(newStr) // fedcba
    

后记

以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得**收藏转发、点击右下角按钮在看**,推荐给更多小伙伴呦,欢迎多多留言交流...

胡哥有话说,一个有技术,有情怀的胡哥!京东开放平台首席前端攻城狮。与你一起聊聊大前端,分享前端系统架构,框架实现原理,最新最高效的技术实践!

长按扫码关注,更帅更漂亮呦!关注胡哥有话说公众号,可与胡哥继续深入交流呦!

胡哥有话说

转载于:https://my.oschina.net/u/4188011/blog/3090206

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
本书高清PDF 86M 收集自网络,请在资源下载后24H内删除,著作权归原书作者。如觉得图书非常有用,请自己购买纸质书籍。 《数据结构算法JavaScript描述》 推荐序  XI 前言  XII 第1 JavaScript的编程环境和模型  1 1.1 JavaScript环境  1 1.2 JavaScript编程实践  2 1.2.1 声明和初始化变量  3 1.2.2 JavaScript中的算术运算和数学库函数  3 1.2.3 判断结构  4 1.2.4 循环结构  6 1.2.5 函数  7 1.2.6 变量作用域  7 1.2.7 递归  9 1.3 对象和面向对象编程  10 1.4 小结  11 第2 数组  13 2.1 JavaScript中对数组的定义  13 2.2 使用数组  13 2.2.1 创建数组  14 2.2.2 读写数组  15 2.2.3 由字符串生成数组  15 2.2.4 对数组的整体性操作  16 2.3 存取函数  17 2.3.1 查找元素  17 2.3.2 数组的字符串表示  18 2.3.3 由已有数组创建新数组  18 2.4 可变函数  19 2.4.1 为数组添加元素  19 2.4.2 从数组中删除元素  20 2.4.3 从数组中间位置添加和删除元素  21 2.4.4 为数组排序  21 2.5 迭代器方法  22 2.5.1 不生成新数组的迭代器方法  22 2.5.2 生成新数组的迭代器方法  25 2.6 二维和多维数组  27 2.6.1 创建二维数组  27 2.6.2 处理二维数组的元素  28 2.6.3 参差不齐的数组  29 2.7 对象数组  30 2.8 对象中的数组  31 2.9 练习  32 第3 列表  33 3.1 列表的抽象数据类型定义  33 3.2 实现列表类  34 3.2.1 append:给列表添加元素  35 3.2.2 remove:从列表中删除元素  35 3.2.3 find:在列表中查找某一元素  35 3.2.4 length:列表中有多少个元素  36 3.2.5 toString:显示列表中的元素  36 3.2.6 insert:向列表中插入一个元素  37 3.2.7 clear:清空列表中所有的元素  37 3.2.8 contains:判断给定值是否在列表中  37 3.2.9 遍历列表  38 3.3 使用迭代器访问列表  39 3.4 一个基于列表的应用  40 3.4.1 读取文本文件  40 3.4.2 使用列表管理影碟租赁  41 3.5 练习  44 第4 栈  45 4.1 对栈的操作  45 4.2 栈的实现  46 4.3 使用Stack类  48 4.3.1 数制间的相互转换  49 4.3.2 回文  50 4.3.3 递归演示  51 4.4 练习  52 第5 队列  53 5.1 对队列的操作  53 5.2 一个用数组实现的队列  54 5.3 使用队列:方块舞的舞伴分配问题  57 5.4 使用队列对数据进行排序  61 5.5 优先队列  63 5.6 练习  65 第6 链表  67 6.1 数组的缺点  67 6.2 定义链表  67 6.3 设计一个基于对象的链表  69 6.3.1 Node类  69 6.3.2 LinkedList类  69 6.3.3 插入新节点  69 6.3.4 从链表中删除一个节点  71 6.4 双向链表  74 6.5 循环链表  78 6.6 链表的其他方法  79 6.7 练习  79 第7 字典  81 7.1 Dictionary类  81 7.2 Dictionary类的辅助方法  83 7.3 为Dictionary类添加排序功能  85 7.4 练习  86 第8 散列  87 8.1 散列概览  87 8.2 HashTable类  88 8.2.1 选择一个散列函数  88 8.2.2 一个更好的散列函数  91 8.2.3 散列化整型键  93 8.2.4 对散列表排序、从散列表中取值  95 8.3 碰撞处理  96 8.3.1 开链法  96 8.3.2 线性探测法  99 8.4 练习  100 第9 集合  101 9.1 集合的定义、操作和属性  101 9.1.1 集合的定义  101 9.1.2 对集合的操作  102 9.2 Set类的实现  102 9.3 更多集合操作  104 9.4 练习  107 第10 二叉树和二叉查找树  109 10.1 树的定义  109 10.2 二叉树和二叉查找树  111 10.2.1 实现二叉查找树  111 10.2.2 遍历二叉查找树  113 10.3 在二叉查找树上进行查找  116 10.3.1 查找最小值和最大值  116 10.3.2 查找给定值  117 10.4 从二叉查找树上删除节点  118 10.5 计数  120 10.6 练习  123 第11 图和图算法  125 11.1 图的定义  125 11.2 用图对现实中的系统建模  127 11.3 图类  127 11.3.1 表示顶点  127 11.3.2 表示边  127 11.3.3 构建图  128 11.4 搜索图  130 11.4.1 深度优先搜索  130 11.4.2 广度优先搜索  133 11.5 查找最短路径  135 11.5.1 广度优先搜索对应的最短路径  135 11.5.2 确定路径  135 11.6 拓扑排序  137 11.6.1 拓扑排序算法  137 11.6.2 实现拓扑排序算法  137 11.7 练习  141 第12 排序算法  143 12.1 数组测试平台  143 12.2 基本排序算法  145 12.2.1 冒泡排序  145 12.2.2 选择排序  148 12.2.3 插入排序  150 12.2.4 基本排序算法的计时比较  151 12.3 高级排序算法  153 12.3.1 希尔排序  153 12.3.2 归并排序  158 12.3.3 快速排序  163 12.4 练习  167 第13 检索算法  169 13.1 顺序查找  169 13.1.1 查找最小值和最大值  172 13.1.2 使用自组织数据  175 13.2 二分查找算法  177 13.3 查找文本数据  183 13.4 练习  185 第14 高级算法  187 14.1 动态规划  187 14.1.1 动态规划实例:计算斐波那契数列  188 14.1.2 寻找最长公共子串  191 14.1.3 背包问题:递归解决方案  194 14.1.4 背包问题:动态规划方案  195 14.2 贪心算法  196 14.2.1 第一个贪心算法案例:找零问题  196 14.2.2 背包问题的贪心算法解决方案  197 14.3 练习  199 封面介绍  200
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页