一、求数组极值
/*
* 目标:
* 1. 求数组极值
* 2. 掌握call、 ... 扩展运算符 / apply 方法求极值
* */
// 需求:求一个数组中的最大值和最小值;
let ary = [12, 1, -1, 0, 22];
// 1. 先排序,再取极值 sort 方法
// 求最大值:给数组降序排列(sort 方法给原数组排序)
ary.sort(function (a, b) {
return b - a; // 降序
});
// ary 经过排序后,最大值是数组的第一项,从数组中取值只能通过[索引]把数组项取出;
let max = ary[0];
// 求最小值:给数组升序排序
ary.sort(function (a, b) {
return a - b; // 升序
});
// 排序后最小的在数组的第一项,
let min = ary[0];
// console.log(max, min);
// 服务端给的数据大多数情况下都是服务端在查数据库的时候已经排好序了,使用的是 SQL 的关键字; SQL 语句中, asc 是指定列按升序排列,desc 则是指定列按降序排列。
// 2. 假设法
// 求最大值:假设数组的第一项是最大值,
// 然后从第二项开始和假设的最大值比较,
// 如果后面的值比假设值大,就把假设值改成较大的值;
let max1 = ary[0]; // 假设第一个是最大值
for (let i = 1; i < ary.length; i++) {
if (ary[i] > max1) {
max1 = ary[i];
}
}
console.log(max1);
// 求最小值:假设数组的第一项是最小值;
// 然后从第二项开始和假设值比较
// 如果后面的值比假设值小,就把假设值改成较小值;
let min1 = ary[0]; // 假设第一个值是最小值
for (let j = 1; j < ary.length; j++) {
if (ary[j] < min1) {
min1 = ary[j];
}
}
console.log(min1);
// 3. 排序算法
// 4. Math.max() Math.min(); 但是 Math.max() 和 Math.min() 只能接受一个一个的参数;
// ? 思考:怎么让这个 Math.max 接受数组作为参数或者把数组变成一项一项的;?
// let max3 = Math.max(1, 2, 3, 4, 5, 6);
// let min3 = Math.min(1, 3, 5, 7, 9);
// ...数组 扩展运算符(ES6 新增运算符):把数组变成一项一项的;
let max4 = Math.max(...ary); // ...ary 把数组变成一项一项的
let min4 = Math.min(...ary);
console.log(max4, min4);
// 让 Math.max 和 Math.min 接受一个数组:使用 apply 方法,可以打包传递参数
let max5 = Math.max.apply(null, ary);
let min5 = Math.min.apply(null, ary);
console.log(max5, min5);
// 5. 把数组 toString(),然后再 eval 求值放
// eval 方法把字符串识别成js代码,并执行;比较消耗性能,尽量少用;
let aryStr = ary.toString(); // "12, 1, -1, 0, 22"
eval(`Math.max(${aryStr})`);
eval(`Math.min(${aryStr})`);
二、类数组转数组
/*
* 目标:
* 1. 类数组:arguments、 DOM 集合
* 2. 类数组转数组
* */
// 类数组:有索引、有 length 的对象;
// 常见的类数组:arguments、 DOM 元素对象集合
let divList = document.getElementsByClassName('box');
// divList.slice(1, 3);
// console.log(divList);
// 数组有很多方法,但是只能给数组的实例用。所以如果能将类数组转成数组,这些方法就可以使用了;
// 类数组转数组的方法:
// 1. 准备一个新数组,遍历类数组对象,把类数组中的每一项 push 到新数组中。
var newAry = [];
for (var i = 0; i < divList.length; i++) {
newAry.push(divList[i]);
}
newAry.slice(1, 3);
// console.log(newAry);
// 2. 把类数组对象通过扩展运算符展开到一个数组中;ES6 新增的方法,老旧浏览器不兼容
let ary1 = [...divList];
// console.log(ary1);
// console.log(Array.isArray(ary1));
// 3. 借用数组原型上的 slice 方法
// 借用 Array.prototype.slice() 方法,在 slice 执行时,把 slice 中的 this 修改类数组,就可以实现把类数组转成数组;
let ary2 = Array.prototype.slice.call(divList);
// console.log(ary2);
// console.log(Array.isArray(ary2)); // true
// 简写方式:IE 低版本会报错;
let ary3 = [].slice.call(divList); // Array.prototype.slice 直接访问 Array 的原型对象的 slice
// 方法;[].slice 使用[] 空数组的原型链查找机制找到 slice 方法;
// console.log(ary3);
// console.log(Array.isArray(ary3)); // true
// 4. Array.from() ES6 新增的方法,把类数组对象(类数组结构、iterator对象)转变成数组;IE 低版本不兼容
let ary4 = Array.from(divList);
console.log(ary4);
console.log(Array.isArray(ary4));