javascript 数据结构和算法读书笔记 > 第二章 数组
这章主要讲解了数组的工作原理和其适用场景。
定义:
一个存储元素的线性集合,元素可以通过索引来任意存取,索引通常是数字,用来计算元素之间存储位置的偏移量。
javascript数组的特殊之处:
javascript中数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性,索引可能是整数,但是这些整数会被转化为字符串。
这是因为javascript中对象的属性必须死字符串类型。
1. 数组的基本操作
a) 创建数组
声明空的数组:
// 1. 使用new关键字 var arr1 = new Array(); // 2. 使用中括号(推荐) var arr2 = [];
初始化:
// new 的方式一个参数 var arr1 = new Array(5); console.info(arr1.length); --> 5 // 多个参数 var arr2 = new Array(1,2,3,4,5); console.info(arr2.length); --> 5 // [] 方式 var arr3 = [1,2,3,4,5]; console.info(arr3.length); --> 5
可以调用Array.isArray方法,判断是否为数组
var num = 3; var arr = ['a', 12, true, null]; console.info(Array.isArray(num)); -> false console.info(Array.isArray(arr)); -> true
b) 读写数组
利用循环写数组:
var arr = []; for(var i=0;i<10;i++){ arr[i] = i; }
利用循环读取:
var arr = [1,2,3,4,5]; for(var i=0;i<arr.length;i++){ console.info(arr[i]); }
c) 由字符串生成数组
字符串对象调用 split 方法也可以生成数组
split方法就是根据某一个特定字符将字符串拆分为多条数据
var str = "you are a great javascripter". var arr = str.split(' '); for(var i=0;i<arr.length;i++){ console.info(arr[i]); } =》 you =》 are =》 a =》 great =》 greate =》 javascripter
d) 对数组的整体性操作
从一个数组对另一个数组复制
var a = [5, 11]; var b = a; console.info(b[0]); =>5 a[0] = 1; console.info(b[0]); =>1
我们可以看到,在首次赋值时,数组b确实是拥有和a一样的值,但是将原有的a数组中的数据进行改变后,b数组中也随之改变,
说明了我们赋值给b的知识a数组的引用。这种赋值方式也叫做浅拷贝。
为了达成深拷贝,必须每个值依依复制:
function copyArr(org, dest){ for(var i=0; i<org.length; i++){ dest[i] = org[i]; } } var a = [5, 11]; var b = copyArr(a, b); console.info(b); =>5,11 a[0] = 1; console.info(b); =>1,11
2.存取函数
a) 查找元素
indexOf()是javascript中最常用的查找函数,参数为你要查找的内容,返回为该内容所在的下标位置,没有时返回-1,若是有多个相同元素则返回第一次出现的位置。
var arr = ['David', 'Jason', 'Kerry', 'Jimmy','Kerry']; var index = arr.indexOf('Jimmy'); console.info(index); => 3 index = arr.indexOf('Owen'); console.info(index); => -1;index = arr.indexOf('Kerry');console.info(index); => 2
如果想获取最后一次出现的位置使用lastIndexOf()方法即可。
b) 数组的字符串表示
有两个方法可以讲数组转为字符串 join(str)和toString()
var arr = ['a', 'b', 'c']; var str1 = arr.join(); console.info(str1); => "a,b,c"; var str2 = arr.toString(); console.info(str2); => "a,b,c";
与其他语言类似直接打印一个非String类型变量的时候,会自动调用其toString()方法。
c) 由已有数组创建的新数组
javascript中有两个方法去通过原有数组创建新数组。
ArrayObject.concat(ArrayObject) 用于合并数组
var arr1 = [1, 2, 3, 4, 5]; var arr2 = [6, 7, 8, 9, 10]; var arr = arr1.concat(arr2); > arr1 [1, 2, 3, 4, 5] > arr2 < [6, 7, 8, 9, 10] > arr < [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以看到被操作数组arr1和arr2没有被改变,concat方法的返回值为二者合并后的结果。
ArrayObject.splice(index, length) 用于截取数组
var arr1 = [1, 2, 3, 4, 5]; var arr2 = [6, 7, 8, 9, 10]; var arr = arr1.concat(arr2); var _arr = arr.splice(1,2); > arr < [1, 4, 5, 6, 7, 8, 9, 10] > _arr < [2, 3]
该方法会修改原有数组中的内容。
3.可变函数
a) 添加
在数组的末尾添加:
方法一:
var arr = [1, 2, 3, 4, 5]; arr.push(6); > arr < [1,2,3,4,5,6]
方法二:
var arr = [1, 2, 3, 4, 5]; arr[arr.length] = 6; > arr < [1,2,3,4,5,6]
方法一比方法二更加直观些。
在数组开头增加元素:
方法一:
var arr = [1, 2, 3, 4, 5]; var len = arr.length; for (var i = len; i >= 1; i--) { arr[i] = arr[i-1]; // 将原有的数据向后移动一位 } arr[0] = 0; // 第一个元素为要添加的元素 > arr < [0,1,2,3,4,5]
方法二:
var arr = [1, 2, 3, 4, 5]; var newnum = 0; arr.unshift(newnum); > arr < [0,1,2,3,4,5] arr.unshift(6, 7, 8); > arr < [6, 7, 8, 0, 1, 2, 3, 4, 5]
b) 删除
将数组最后一个元素删除:
var arr = [1, 2, 3, 4, 5]; var num = arr.pop(); // newnum用来保存删除的元素
> arr < [1, 2, 3, 4] > num < 5
讲述组第一个元素删除:
方法一:
var arr = [1, 2, 3, 4, 5]; var len = arr.length; for(var i=0; i<len-1;i++){ arr[i] = arr[i+1]; } arr.length = len - 1; > arr < [2, 3, 4, 5]
方法二:
var arr = [1, 2, 3, 4, 5]; var newnum = arr.shift(); // newnum用来保存删除的元素 > arr < [2, 3, 4, 5] > newnum < 1
方法二更为高效和直观些。
c) 在确定位置添加和删除
使用之前提到过的splice方法即可:
var arr = [1, 2, 3, 4, 5]; // 末尾添加 arr.splice(arr.length, 0, 6); // = > [1, 2, 3, 4, 5, 6] // 开头添加 arr.splice(0, 0, 0); //= > [0, 1, 2, 3, 4, 5, 6] // 从第二为开始删除3个元素 arr.splice(2, 3); // = > [0, 1, 5, 6] // 从第二位起,添加元素2, 3, 4 arr.splice(2, 0, 2, 3, 4); // = > [0, 1, 2, 3, 4, 5, 6]
d) 为数组排序
翻转:
var arr = [1, 2, 3, 4, 5]; // 对数组进行翻转 console.info(arr.reverse()); // = > [5, 4, 3, 2, 1] // arr 数组直接被修改 console.info(arr); // = > [5, 4, 3, 2, 1]
排序:
对于字符串使用 sort 方法效果不错:
var arr = ['Bonnee', 'Demon', 'Stefan', 'Elena', 'Jeremy']; arr.sort(); console.info(arr); // = > ["Bonnee", "Demon", "Elena", "Jeremy", "Stefan"]
可以看到对于字符串使用sort方法,会根据首字母的顺序进行排列。
但是对于数字排序如果我们直接使用sort方法就会出现奇怪的东西了:
var arr = [5, 30, 2, 400, 1]; arr.sort(); console.info(arr); // = > [1, 2, 30, 400, 5]
其实sort方法中我们还缺少了一个参数,作为比较的方法判断函数。如果不加这个函数时,sort方法会将数组中的元素进行字典排序,不会进行大小排序。
var arr = [5, 30, 2, 400, 1]; // 正序排列 arr.sort(function(x, y){ return x - y; }); console.info(arr); // = > [1, 2, 5, 30, 400] // 倒序排列 arr.sort(function(x, y){ return y - x; }); console.info(arr); // = > [400, 30, 5, 2, 1]
4.迭代器方法
a) 不生成新数组的迭代器方法
forEach方法(不能写成 foreach ), 用于对数组中每个元素都进行相同操作
var arr = [1, 2, 3, 4, 5, 6]; var square = function(x){ console.info(x, x*x); }; arr.forEach(square); --------------------------------- 1 1 2 4 3 9 4 16 5 25 6 36 ---------------------------------
every方法,用于对每个元素进进行统一判断,最后返回boolean值。如果有一个值为false就返回false,所有为true才会返回true
如判读一组数是否都为偶数:
var arr = [1, 2, 3, 4, 5, 6]; var isEven = function(x){ return x%2 === 0; }; var rs = arr.every(isEven); if(rs){ console.info("all the number in the array are even."); }else{ console.info("not all the number in the array are even."); } ----------------------------------------------- not all the number in the array are even. -----------------------------------------------
some 方法,如果一个值返回true,则会返回true,所有为false才会为false
如判断一组数中是否有偶数:
var arr = [1, 2, 3, 4, 5, 6]; var isEven = function(x){ return x%2 === 0; }; var rs = arr.some(isEven); if(rs){ console.info("some number in the array are even."); }else{ console.info("all the number in the array are not even."); } ------------------------------------------ number in the array ------------------------------------------
reduce方法,一般用于累加:
var arr = [1, 2, 3, 4, 5, 6]; var add = function(runningNum, currentNum){ return runningNum + currentNum; }; var rs = arr.reduce(add); // = > 21
reduceRight方法,从右到左进行累加
var strArr = [' Paper',' are','You']; var joinStr = function(runningStr, currentStr){ return runningStr + currentStr; }; var rsStr = strArr.reduceRight(joinStr); // = 》 "You are Paper"
b) 生成新数组的迭代器方法
所谓生成新数组就是对数组中的元素依次改变,最后返回一个由改变的元素组成的新的数组对象
map方法
var strArr = [' Paper', ' are', ' You']; var delSpace = function(x){ return x.replace(/\s/g, ''); }; var rsArr = strArr.map(delSpace); // = > ["Paper", "are", "You"]
filter方法
和其名称一样,filter会根据你传入的函数,过滤掉为false的元素
如过滤掉无用元素:
var strArr = ['a','', null, 'c', undefined]; var rsArr = strArr.filter(function(x){ return x; }); // => ["a", "c"]
5.二维和多维数组
a) 创建二维数组
创建二维数组首先要创建一个一维数组,然后其中每个元素都为一个一维数组就行了:
var arr = []; var len = 5; for (var i = 5 - 1; i >= 0; i--) { arr[i] = []; }; > arr < [Array[0]length: 0__proto__: Array[0], Array[0]length: 0__proto__: Array[0], Array[0]length: 0__proto__: Array[0], Array[0]length: 0__proto__: Array[0], Array[0]length: 0__proto__: Array[0]]
其实我们也可以再Array上直接添加方法:
Array.matrix = function(row, col, init){ var arr = []; for(var i=0; i<row; i++){ var temp = []; for(var j=0;j<col; j++){ temp[j] = init; } arr[i] = temp; } return arr; }; var arr = Array.matrix(3, 4, 1); console.info(arr[2][3]); // = > 1
或者直接初始化:
var arr = [[43,23],[52,1],[2,4]];
b) 处理二维数组的元素
按行处理:
arr 用以保存 3 名学生 3 门课的成绩,求每个学生的平均成绩:arr 用以保存 3 名学生 3 门课的成绩
var arr = [[98,77,89],[77,66, 59],[92,82,89]]; for(var i=0; i<arr.length; i++){ var total = 0, average = 0.0; var currentStu = arr[i]; for(var j=0; j<currentStu.length; j++){ total += currentStu[j]; } average = total/currentStu.length; console.info("Student " + parseInt(i) + ": " + average.toFixed(2)); } -------------------------------- Student 1: 88.00 Student 2: 67.33 Student 3: 87.67 --------------------------------
按列处理:
arr 用以保存 3 名学生 3 门课的成绩,求每门课的平均成绩:
var grades = [[89, 77, 78] , [76, 82, 81] , [91, 94, 89], [71, 83, 74]] ; var total = 0; var average = 0.0; var courseNum = 3; var stuNum = grades.length; // 已知有三门课程 for (var col = 0; col < courseNum; ++col) { for (var row = 0; row < stuNum; ++row) { total += grades[row][col] ; } average = total / stuNum; console.info("Course " + parseInt(col+1) + " average: " + average. toFixed(2)); total = 0; average = 0.0; } ------------------------------------------- Course 1 average: 81.75 Course 2 average: 84.00 Course 3 average: 80.50 -------------------------------------------
c) 参差不齐的数组
和之前一样,没有变化:
var arr = [[98,77,89],[77,66,59, 82, 78],[92,82,89,33]]; for(var i=0; i<arr.length; i++){ var total = 0, average = 0.0; var currentStu = arr[i]; for(var j=0; j<currentStu.length; j++){ total += currentStu[j]; } average = total/currentStu.length; console.info("Student " + parseInt(i) + ": " + average.toFixed(2)); } --------------------------------------- Student 0: 88.00 Student 1: 72.40 Student 2: 74.00 ---------------------------------------
6.对象数组
和普通类型的数组没有什么区别,都可以使用以上提到过的方法。
7.对象中的数组
以上面提到过的学生成绩和求该学生的平均成为为例:
var StuGrade = function(){ var total = 0; this.grades = []; this.add = function(grade){ this.grades.push(grade); total += grade; }; this.average = function(){ return total / this.grades.length; }; }; var stu1 = new StuGrade(); stu1.add(80); stu1.add(73); stu1.add(88); stu1.add(92); console.info(stu1.grades); // = > [80, 73, 88, 92] console.info(stu1.average()); // = > 83.25
第二章知识思维导图:
javascript 数据结构和算法读书笔记 > 第二章 数组的更多相关文章
- javascript 数据结构和算法读书笔记 > 第一章 javascript的编程环境和模型
1.变量的声明和初始化 必须使用关键字 var,后跟变量名,后面还可以跟一个赋值表达式. var name; var age = 5; var str = 'hello'; var flg = fal ...
- javascript 数据结构和算法读书笔记 > 第五章 队列
队列是一种列表,但是它只能够在队尾插入元素,在队首删除元素.队列用于存储按照顺序排列的数据,先进先出.而栈则是后入栈的元素反而被优先处理. 实际中一般被应用在进程池.排队操作上面. 1. 队列的操作 ...
- javascript 数据结构和算法读书笔记 > 第四章 栈
1. 对栈的操作 栈是一种特殊的列表,栈中的元素只能通过列表的一端进行访问,即栈顶.类似于累起一摞的盘子,只能最后被放在上面的,最先能被访问到. 就是我们所说的后入先出(LIFO). 对栈主要有入栈p ...
- javascript 数据结构和算法读书笔记 > 第三章 列表
1. 结构分析 列表首先要有以下几个属性: listSize 长度 pos 当前位置 dataStore 数据 我们要通过以下方法对上面三个属性进行操作: length() 获取长度 | getPos ...
- 《javascript权威指南》读书笔记——第二篇
<javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...
- 为什么我要放弃javaScript数据结构与算法(第六章)—— 集合
前面已经学习了数组(列表).栈.队列和链表等顺序数据结构.这一章,我们要学习集合,这是一种不允许值重复的顺序数据结构. 本章可以学习到,如何添加和移除值,如何搜索值是否存在,也可以学习如何进行并集.交 ...
- 为什么我要放弃javaScript数据结构与算法(第五章)—— 链表
这一章你将会学会如何实现和使用链表这种动态的数据结构,这意味着我们可以从中任意添加或移除项,它会按需进行扩张. 本章内容 链表数据结构 向链表添加元素 从链表移除元素 使用 LinkedList 类 ...
- 为什么我要放弃javaScript数据结构与算法(第十一章)—— 算法模式
本章将会学习递归.动态规划和贪心算法. 第十一章 算法模式 递归 递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.递归通常涉及函数调用自身. 递归函数是像下面能够直接调用自身的 ...
- 为什么我要放弃javaScript数据结构与算法(第七章)—— 字典和散列表
本章学习使用字典和散列表来存储唯一值(不重复的值)的数据结构. 集合.字典和散列表可以存储不重复的值.在集合中,我们感兴趣的是每个值本身,并把它作为主要元素.而字典和散列表中都是用 [键,值]的形式来 ...
随机推荐
- tostring的用法
ToString()可空参数单独使用,同时可以加一个格式化参数,具体方式如下: . 取中文日期显示_年月 currentTime.ToString("y"); 格式:2007年1月 ...
- CodeForces 501B - Misha and Changing Handles
有N个改名的动作,输出改完名的最终结果. 拿map做映射 #include <iostream> #include <map> #include <string> ...
- CDZSC_2015寒假新人(1)——基础 e
Description Julius Caesar lived in a time of danger and intrigue. The hardest situation Caesar ever ...
- C#生成缩略图的方法
1.需要添加应用System.Drawing.dll 2.命名空间 using System.IO; using System.Drawing; using System.Drawing.Imagin ...
- Angular中Controller之间的信息传递(第二种办法):$emit,$broadcast,$on
$emit只能向parent controller传递event与data( $emit(name, args) ) $broadcast只能向child controller传递event与data ...
- strace排除Linux服务器故障
strace是一个有用的小工具 – 大多数Linux系统默认已经安装 – 可以通过跟踪系统调用来让你知道一个程序在后台所做的事情.Strace是一个基础的调试工具;但是即便你不是在跟踪一个问题的时候它 ...
- Python学习笔记(五)Python的切片和迭代
切片 Python提供了切片操作符,可以对list.tuple.字符串进行截取操作. list中的切片应用 语法如下: >>> L = ['Michael', 'Sarah', 'T ...
- Python Challenge 过关心得(0)
最近开始用Openerp进行开发,在python语言本身上并没有什么太大的进展,于是决定利用空闲时间做一点python练习. 最终找到了这款叫做Python Challenge(http://www. ...
- ruby和Python简单对比
前不久学了ruby,发现ruby和Python非常像,于是自个测试对比了下,测完了才知道网上有现成的……下面是测试结果 序列(包括列表和元组等)有分片的特点:可能会比较方便的提取其中特定元素,暂时 ...
- C#中委托和事件
目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...