10_JavaScript数组排序和高阶方法
目录
一、数据类型之间存储的区别(重点)
二、数据类型之间的比较
三、数组的排序
3.1 sort 排序
3.2 冒泡排序
3.3 选择排序
四、 数组的高阶方法
forEach 遍历
map(映射)
一、数据类型之间存储的区别(重点)
-
数据类型分成
-
基本数据类型
-
number string boolean null undefined
- 复杂数据类型
Object Array ....
可以通过new 关键字创建出来的对象 都是复杂数据类型
数据类型存储区别
-
我们的变量在内存里,存储空间里分成两种 堆和栈
-
栈内存:比较小的内存:主要存储基本数据类型
-
堆内存:比较大的内存:主要存储复杂数据类型
var num = 10;
var num2 = num;
num2 = 200
console.log(num);//10
console.log(num2);//200
相当于把num的值复制了一份给num2
-赋值以后两个数据没有关系 互不影响,修改其中一个不会影响另一个
堆内存:
-
在堆里边开辟出一个存储空间
-
把数据存储到存储空间里
-
把存储空间的地址赋值给栈内存中的变量
var obj = {
name:"jack",
age:18,
gender:"男"
}
var obj2 = obj;
obj2.name="rose";
console.log(obj,obj2);
- 因为复杂数据类型,变量存储的是地址,真实的内容在堆空间里存储
- 所以赋值时相当一把obj的地址复制了一份给了obj2
- 现在obj 和 obj2两个变量的地址是一致,指向了相同的一个内存空间
- 所以修改obj2的内容时,obj也跟着改
二、数据类型之间的比较
-
基本数据类型 是 值的比较
-
复杂数据类型是 地址的比较
var num = 1;
var str = "1";
console.log(num == str); //true
var obj = {name:"jack"};
var obj2 = {name:"jack"};
console.log(obj == obj2);//false
- 创建了2个对象,那么会在堆内存中开辟出两个内存空间(两个地址)
- 虽然存储的数据是一样的,但是这是两个 不同的地址
- 复杂数据类型是 **地址**的比较 因为obj 和 obj2 是不同的地址 所以 false
例子:
var num = 100;
function fn(n){
n = 200;
console.log(n); //200
}
fn(num);
console.log(num); //100
- 和之前的变量赋值一样,在把num的值复制了一根一模一样的给了函数内部的形参
- 两个num 和 n之间没有任何关系!!
function fn(o){
o.age = 30;
console.log(o.age); //30
}
var obj = {
age:18
}
fn(obj);
console.log(obj.age); //30
- 和之前的变量赋值一样,把obj的内存地址复制了一份给形参o
- 函数外部的obj 和 o 指向的是同一个内存地址
- 修改一个,另一个也会修改**
三、数组的排序
-
排序,就是把一个乱序的数组,通过处理,变成一个有序的数组
-
今天主要讲2中排序算法 冒泡排序、选择排序
3.1 sort 排序
var arr = [12,3,4,66,8,1,99];
arr.sort(function(a,b){
return a-b
})
console.log(arr);
3.2 冒泡排序
冒泡排序的原理:
先遍历数组,让挨着的两个元素进行比较,如果前一个比后一个大,那么就把这两个换个位置
数组遍历一遍之后,那么最后一个数字就是最大的那个
然后进行第二次遍历,还是按照之前的规则,第二大的数字就会到倒数第二的位置
以此类推,最后就会把数组排好序
// 外侧的循环 代表数组遍历的次数
var arr1 = [2,1,88,99,22,66,3,67];
for (var i = 0; i < arr1.length - 1; i++) {
// 在这个循环里边也要执行多次,继续循环,里边的循环代表的是比较的次数
for (var j = 0; j < arr1.length - 1 - i; j++) {
// j =0 比较8次 j<8 执行了8次
// j =1 比较7次 j<7 执行了7次
// j =2 比较6次 j<6 执行了6次
// 如果前一个比后一个大,就交换位置
if (arr1[j] > arr1[j + 1]) {
var tmp = arr1[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = tmp;
}
}
}
console.log(arr1);
3.3 选择排序
-
先假定数组中的第0个就是最小的数字的索引
var minIndex = 0;
-
然后遍历数组,只要有一个数字比我小,就替换之前的索引
-
直到数组遍历结束后,就能找到最小的索引,然后让最小的索引换到第0个位置
-
再来第二次遍历,假定第一个是最小数字的索引
-
以此类推
var arr = [8,7,6,99,66,5,33,1,99];
// 先假定数组中的第0个就是最小的数字的索引 `var minIndex = 0;
var minIndex = 0;
// 然后遍历数组,只要有一个数字比我小,就替换之前的索引
// i=0 循环第一次 比较4次
// 5,66,33,44,99
// i=1 循环第二次 比较3次
// 5,33,66,44,99
// i=2 循环第四次 比较2次
// 5,33,44,66,99
// i=3 循环第五次 比较1次
// 5,33,44,66,99
// 外侧的循环代表的是数组遍历的次数
for(var i=0;i<arr.length-1;i++){
var minIndex = i;
for(var j = i + 1; j < arr.length; j++){
// j的值 让她由i决定
// j = 1 j<5 比较4次
// j = 2 j<5 比较3次
// j = 3 j<5 比较2次
// j = 4 j<5 比较1次
if(arr[j]<arr[minIndex]){
// 如果后一个比前一个小,索引值改变
// minIndex 保存的始终是最小的那个值的索引
minIndex = j;
}
}
console.log(minIndex);//最小的那个值的索引
// 交换位置 改变数组元素的位置
// i 0 1 2 3 4 外侧数组的索引 minIndex 3
if(minIndex!==i){
// 交换
var tmp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = tmp;
}
}
console.log(arr);
四、 数组的高阶方法
-
之前讲的数组的方法都是es3的方法
-
es ecma 标准
-
es3 95年
-
es5 09年
-
es6 2015年 (更新比较大)
-
从es6之后 每一年都会更新一版
-
-
数组的高阶方法
-
indexOf (不算高阶方法,是es5 有的)
-
lastIndexOf
-
-
forEach 遍历
-
forEach 本身是个函数,接受一个参数,这个参数也是一个函数
-
语法:
arr.forEach(function(item,index,arr){})
-
数组的长度是多少,就会执行多少次
-
没有返回值
-
// forEach
arr.forEach(function(item,idx,ary){
console.log(item,idx,ary);
})
item 代表数组的每一项元素
idx 代表数组的下标
ary 代表原数组
var arr = [1,2,66,77,88,99];
// for for in for of
// forEach
var res = arr.forEach(function(item,idx,ary){
//console.log(item,idx,ary);
console.log("数组元素是"+item+",索引是"+idx+",原数组是"+ary);
})
console.log(res);//undefined
map(映射)
-
map 本身是个函数,接受一个参数,这个参数也是一个函数
-
语法:
arr.map(function(item,index,arr){})
-
数组的长度是多少,就会执行多少次
-
有返回值,返回一个新的数组,不修改原数组
var arr = [1,2,3,4,5,6,7];
var res = arr.map(function(item,idx,ary){
// console.log(item,idx,ary);
return item+10
})
console.log(res);
三个参数 item idx ary 不是都必须写
如果你只用到了item 就写item即可
var arr1 = [{
name: "lis",
age: 18
}, {
name: "lis",
age: 18
}, {
name: "lis",
age: 18
}];
var res1 = arr1.map(function(item){
return {
name:"lis",
age:20
}
})
console.log(res1,arr1);
作业
公司招聘10个员工,(性别,年龄,月薪各有不同),有以下需求
var employees = [{
name:"A",sex:"男",age:18,salary:10000
},{ name:"B",sex:"男",age:28,salary:12000}]
-
列表展示所有员工的所有信息 (我的名字是XXX,性别是XXX,年龄是XXX,月薪是XXX)
-
对员工的工资,降序排序
-
得到男员工的总月薪