day4JS-数组

1. 什么是数组

  • 数组是值的有序集合
  • 每个值叫做一个元素
  • 每个元素在数组中有一个位置, 以数字表示,称为索引 (有时也称为下标)。
  • 数组的元素可以是任何类型。
  • 数组索引从 0 开始,数组最大能容纳 4294967295 个元素。

2. 数组的声明与使用

2.1 使用字面量的方式声明数组

语法:var/let 数组名 = [元素,元素,...];

// 定义所有的姓名组成的集合
var nameList = ['小王', '小李', '张三'];

//定义由数字组成的数组
var numList = [112,232,34,34234,3434,3434,121,112,112,112];

//数组的元素各种类型都有
var list = ['张三', 100, true, false, '李四', [1, 2, 3]];

2.2 读写数组元素

1. 使用操作符 [ ] 读写数组的每一个元素,[ ]中是数组的索引

语法: 数组名[索引下标];

// 读取数组中元素的值
nameList[12];

// 给数组中的元素赋值
nameList[2] = 100;

2. 数组可以通过 length 属性获取数组的长度,也就是数组中元素的个数

语法: 数组名.length;

nameList.length; // 获取数组 nameList 的长度

3. 如果数组索引超过数组的长度数组[大于元素个数的索引] = 值是这个写法有赋值相当于新增。如果是数组[大于元素个数的索引]这个写法是直接访问没有的索引默认值为undefined

var ary=[1,2,3];
ary[3]=200;//相当于新增一个
ary[5]=300;
console.log(ary);//[1, 2, 3, 200, empty, 300]
console.log(ary[4]);//undefined

4. 数组length属性的特别之处(他不是只读的,通过修改length,可以从数组末尾删除或添加元素)。

let colors=['red','blue','green'];
colors.length=2;
console.log(colors[2])//undefined
ary.length=7;//新增的元素都用undefined填充
ary[ary.length]='black';//数组最后添加一个

2.3 遍历数组(迭代)

使用 for循环或 for in 循环

// for 循环遍历
for (var i = 0; i < arr.length; i ++) {
    arr[i]
}

//for in 循环
for (var i in arr) {
    arr[i]
}

2.4 多维数组

// 创建多维数组
var cityList = [
  ['广州', '深圳', '佛山', '东莞', '惠州'],
  ['南京', '苏州', '徐州', '无锡', '南通'],
  ['济南', '青岛', '烟台', '潍坊', '淄博'],
  ['杭州', '宁波', '温州', '绍兴', '湖州']
];

// 多维数组取值
cityList[2][1];
for (let i = 0; i < cityList.length; i++) {
				for (let j = 0; j < cityList[i].length; j++) {
					console.log(cityList[i][j]);
				}
			}

3. 数组方法15个

3.1 push(数据...)(后增)

  • 作用:向数组末尾追加某一项。

  • 参数:添加的具体项,可以是一项,也可以是多项

  • 返回值:新数组的长度

  • 是否改变原数组:改变

var colors = ['red', 'pink'];
var res = colors.push('blue');
// 原数组
console.log(colors);//['red', 'pink', 'blue']
// 返回值
console.log(res);//3

3.2 pop()(后删)

  • 作用:删除数组的最后一项

  • 参数:

  • 返回值:删除的项

  • 是否改变原数组:改变

var colors = ['red', 'pink'];
var res = colors.pop();
// 原数组
console.log(colors);//['red']
// 返回值
console.log(res);//'pink'

3.3 unshift(数据...)(前增)

  • 作用:向数组的开头添加内容。

  • 参数:添加的内容。

  • 返回值:新数组的长度

  • 是否改变原数组:改变

var colors = ['red', 'pink'];
var res = colors.unshift('blue', 'green');
// 原数组
console.log(colors);//['blue', 'green', 'red', 'pink']
// 返回值
console.log(res);//4

3.4 shift(前删)

  • 作用:删除数组第一项

  • 参数:无。

  • 返回值:删除的项

  • 是否改变原数组:改变

var colors = ['red', 'pink'];
var res = colors.shift();
// 原数组
console.log(colors);//['pink']
// 返回值
console.log(res);//red

3.5 reverse()(反排)

  • 作用:把数组元素反向排列

  • 参数:无。

  • 返回值:是排序后的新数组

  • 是否改变原数组:改变

var ary=[1,2,3];
var res=ary.reverse();
console.log(res);//[3,2,1];
console.log(ary);//[3,2,1];

3.6 sort ()(排序)

  • 作用:把数组进行排序

  • 参数:或者有一个函数

  • 返回值:排序后的新数组

  • 是否改变原数组:改变

注意!!!

如果是排序的数是多位数sort ()不传参的时候是无法进行排序的,这时sort ()必须传参

//----------------------不传参的时候

//=====>10 以内的可以排
var ary=[3,2,1,6,8];
ary.sort();

[1, 2, 3, 6, 8]

//=====> 超出10
 var ary2=[1,21,5,33,26]
 ary2.sort();
 [1, 21, 26, 33, 5];
 
 //---------------------------传参的时候
 var ary2=[1,21,5,33,26]
 ary2.sort(function(a,b){
    return a-b; // 升序
    return b-a; //降序
 })

3.7 splice()(增删改一体化)

  • 作用:删除/新增/修改

  • 参数:splice(n,m,...x)不能传负数

  • 返回值:删除/新增/修改的元素

  • 是否改变原数组:改变

3.7.1 删除

  • 删除需要给splice传递两个参数
  • 第一个参数:要删除的第一个元素的位置
  • 第二个参数:要删除的元素数量
  • 返回值:删除的内容放在新数组中返回

语法: 数组名.splice(开始索引位置, 删除的个数);

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(0, 2);
console.log(nums);// [3, 4, 5, 6]
console.log(res);// [1,2]

3.7.2 新增

新增需要传递3个参数新增的内容在开始索引的前面

第一个参数:开始的位置

第二个参数:0(要删除的元素数量)

第三个参数: 要插入的元素(任意个)。

返回值:空数组

语法: 数组名.splice(开始索引位置, 删除的个数为0,新增的内容(可以是多个));

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(3, 0, 7, 8, 9);
console.log(nums);//[1, 2, 3, 7, 8, 9, 4, 5, 6] 
console.log(res);// []

3.7.3 修改

修改也需要传递3个参数

第一个参数:开始的位置

第二个参数:要修改的元素数量

第三个参数: 要插入的元素(任意个)。

返回值:修改的内容放在新数组中返回

语法: 数组名.splice(开始索引位置, 修改的个数,修改的内容(可以是多个));

注意:修改的个数和新增的个数可以不一致

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(0, 3, 7, 8, 9);
console.log(nums);//[7, 8, 9, 4, 5, 6] 
console.log(res);// [1, 2, 3]

3.8 fill()(填充)

  • 作用:填充。
  • 参数:有3个参数。

        第一个参数:填充的内容

        第二个参数:开始索引

        第三个参数:结束索引

  • 返回值:填充后的数组
  • 是否修改原数组:改变

注意!!!

数组.fill(内容,开始索引,结束索引)包头不包尾

数组.fill(内容) :从开头到结尾,就是完全替换

数组.fill(内容,开始索引) 从开始索引到最后

无参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill();
console.log(res);//[undefined,undefined,undefined,undefined,undefined]
console.log(arr);//[undefined,undefined,undefined,undefined,undefined]

有一个参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill(3);
console.log(res);//[3,3,3,3,3]
console.log(arr);//[3,3,3,3,3]

有二个参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill(3, 2);
console.log(res);//[10,20,3,3,3]
console.log(arr);//[10,20,3,3,3]

有三个参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill(3, 0, 2);
console.log(res);//[3,3,30,40,50]
console.log(arr);//[3,3,30,40,50]

两种创建数组方法的区别:

字面量的方法,其实是添加一个内容为5,length为1。

构造函数法,其实是指定数组的length为5,内容为undefined

注意!!!这两种创建数组方法都可以使用普通for循环进行循环。

3.9 slice(截取包前不包后)

  • 作用:从原有的数组中截取特定的内容,放在新数组中,原有的数组不变

  • 参数:可以没有有一个或者有两个

  • 返回值:返回值是截取出来的内容组成的新数组

  • 是否改变原数组:不改变

1. 如果没有参数,slice()会返回整个数组相当于复制数组

语法:  数组名.slice();

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice();
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [1, 2, 3, 4, 5, 6]

2. 如果只有一个参数,slice()会返回该索引到数组末尾的所有元素

语法: 数组名.slice(开始索引);

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(1);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5, 6]

3. 如果有两个参数,slice()返回从开始索引到结束索引对应的所有元素

语法:数组名.slice(开始索引, 结束索引);

但是不包含结束索引 数组名.slice(n,m),包含n,不包含m

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(1, 5);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5]

4. 如果slice()的参数有负值,那么就数组长度加上这个负数来确定位置。

长度为6,slice(-5,-1)就相当于slice(1,5)

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(-5, -1);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5]

5. 如果结束位置小于开始位置,则返回空数组

var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(-1, -5);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// []

3.10 concat(拼接)

  • 作用:实现多个数组或者的拼接。

  • 参数:拼接的内容

  • 返回值:返回值是拼接后的新数组

  • 是否改变原数组:不改变

语法:concat(拼接的内容);

var ary1 = [1, 2, 3];
var ary2 = [4, 5, 6];
var res = ary1.concat(ary2, "快乐", "同学");
console.log(ary1);//[1, 2, 3]
console.log(res);//[1, 2, 3, 4, 5, 6, '快乐', '同学']

3.11 toString(数组转字符串)

  • 作用:可以把数组转换为字符串

  • 参数:无参

  • 返回值:返回值是转换后的字符串

  • 是否改变原数组:不改变

  • 数组中每一个元素转为字符串,然后是使用逗号连接输出显示。

语法:数组名.toString();

var ary1 = [1, { a: 1 }, null, undefined, 3];
var res = ary1.toString();
console.log(ary1);//[1, {a:1},null, undefined, 3]
console.log(res)//1,[object Object],,,3 

alert方法最终体现的是字符串,会调用toString(),所以alert([1,2])结果是1,2

3.12 join(指定连接符)

  • 作用:把数组通过指定的连接符,转换为字符串

  • 参数:无参有参(连接符)

  • 返回值:返回值是转换后的字符串无参默认使用逗号隔开有参默认使用传入的参数内容隔开

  • 是否改变原数组:不改变

1. 无参语法: 数组名.join();

var arr = [1, 2, 3, 4, 6, 7, 8, 9];
let newArr2 = arr.join();
console.log(newArr2)//1,2,3,4,6,7,8,9

2. 有参语法: 数组名.join("连接符"); ,自定义参数拼接。

var arr = [1, 2, 3, 4, 6, 7, 8, 9];
let newArr3 = arr.join("|");
console.log(newArr3)//“1|2|3|4|6|7|8|9”

综合案列:

var ary1 = [1, 2, undefined, 3, { a: 1 }];
var res = ary1.join("|");
console.log(ary1);//[1, 2, undefined, 3, { a: 1 }]
console.log(res)// 1|2||3|[object Object]  
eval(res) //==> eval  执行计算

3.13 indexOf/ lastIndexOf(包含,返回索引下标)

  • 作用:判断数组中是否含有某一项内容,返回含有某一项内容索引下标(有多个相同内容的时候,返回第一个索引下标);不包含返回-1

  • 参数:有2个参数。

        第一个参数:想要判断的内容

        第二个参数:开始索引(默认为0

  • 返回值:-1 或者具体的索引下标

  • 是否改变原数组:不改变。

1. indexOf()语法:索引从左往右开始

有一个参数的时候:
数组名.indexOf(想要判断的内容);

有二个参数的时候:
数组名.indexOf(想要判断的内容,开始索引);

2. lastIndexOf()语法:索引从右往左开始

有一个参数的时候:
数组名.lastIndexOf(想要判断的内容);

有二个参数的时候:
数组名.lastIndexOf(想要判断的内容,开始索引);

案列:

+ 作用:检测数组中的某项在数组中(首次indexOf/最后lastIndexOf)出现的位置

    var ary=[1,2,3,4,1,55,1];
    //检测1这个项目在数组ary 中首次出现的位置
    ary.indexOf(1); //0
    //从索引2开始,检测1这个项目在数组中首次出现的位置
    ary.indexOf(1,2); //4
    
    // 检测1这个项目在数组中最后一次出现的索引
    ary.lastIndexOf(1);
    // 检测1这个项目在数组中最后出现的索引,在索引5的位置停止检测
    ary.lastIndexOf(1,5)
    
    //如果此项在数组中没有出现,返回值就是-1
    ary.indexOf(66)===>-1

3.14 includes(包含,返回布尔值)

  • 作用:判断数组中是否包含某一项

  • 参数:具体内容

  • 返回值:布尔值(true,false)。

  • 是否修改原数组:不改变

var arr = [1, 2, 3, 4, 6, 7, 8, 9];
let res = arr.includes(1);
console.log(res)//true

3.15 flat(数组拍平)

  • 作用:数组扁平化

  • 参数:有参 / 无参 / Infinity

        无参数默认是一层拍平

        有参就是参数是几就是几层拍平

        参数是Infinity就是不管是几层全部都拍平

  • 返回值:拍平后的数组

  • 是否修改原数组:不改变

let arr = [1, 2, [3, 4, ["a", "b", ["A", "B", "C"]]]];
let res1 = arr.flat();
console.log(res1);//[1, 2, 3, 4,["a", "b", ["A", "B", "C"]]]
        
let res2 = arr.flat(2);
console.log(res2);//[1,2,3,4,"a","b",["A","B","C"]]
        
let res3 = arr.flat(Infinity);
console.log(res3);//[1,2,3,4,"a","b","A","B","C"]

4. 数组迭代方法9个

迭代、循环、遍历

4.1 forEach(遍历,不用return)

  • 作用:遍历数组中的每一项,注意forEach中的return不起作用。

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:undefined函数没有return默认值就是undefined

  • 是否修改原数组:不改变

注意!!!

 forEach方法用来遍历数组的每一项, forEach方法没有返回值不用加return

语法:

数组名.forEach( (item,index,array) => {
    
})

案列:

let arr = [10, 20, 30];
let res = arr.forEach((item, index, arr) => {
      console.log(item, index, arr);
})
console.log(res);//undefined

4.2 map(映射,用return)

  • 作用:把一个数组可以映射成一个新的数组

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:映射后的新数组

  • 是否修改原数组:不改变

语法:

数组名.map( (item,index,array) => {
      return  结果;
})

案列:

// 有一个数组装着2021年所有人的年龄,2022年以后,每个人的年龄都增加1岁
var allAge = [19,15,2,30,32,43,45];
var age2020 = allAge.map(function (item,index,arr) {
    return item+1;
})
console.log(age2020);//[20,16,3,31,33,44,46]

4.3 filter(过滤内容)

  • 作用:过滤,把满足条件的内容都查找出来,满足条件看return

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:过滤后的新数组没有过滤到是0

  • 是否修改原数组:不改变

let arr = [10, 20, 30];
let res = arr.filter((item, index) => {
    return item >= 30;
})
console.log(res);//[30]
console.log(arr);//[10, 20, 30]

4.4 find(查找内容)

  • 作用:查找,把满足条件(return)的内容都查找出来,只要第一项

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:查找的那一项查找不到就是undefined

  • 是否修改原数组:不改变

let arr = [10, 20, 30];
let res = arr.find((item, index) => {
    return item > 30;
})
console.log(res);//undefined
console.log(arr);//[10, 20, 30]

4.5 findIndex(查找索引)

  • 作用:查找,把满足条件(return)的内容索引查找出来,只要第一项

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:查找的那项索引值,查找不到就是-1

  • 是否修改原数组:不改变。

let arr = [10, 20, 30];
let res = arr.findIndex((item, index) => {
     return item > 20;
})
console.log(res);//2

4.6 some(条件为或||

  • 作用:数组中有一项满足return条件的就可以。

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:布尔值(true,false)。

  • 是否修改原数组:不改变

let arr = [10, 20, 30, 40, 50];
let res = arr.some((item, index) => {
    return item > 20;
})
console.log(res);//true

4.7 every(条件为与&&

  • 作用:数组中全部都满足return条件的才成立true。不成立为false。

  • 参数:函数。函数有3个形参。

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

  • 返回值:布尔值(true,false)。

  • 是否修改原数组:不改变。

let arr = [10, 20, 30, 40, 50];
let res = arr.every((item, index) => {
    return item > 20;
})
console.log(res);//false

4.8 reduce(用作购物车求和)

  • 作用:一般用于求和

  • 方向:从左到右循环,正序。

  • 参数:函数函数有4个形参。

        sum : 和

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

        有传实参时,相当于给sum赋初始值,item则从该数组索引0处开始循环。如果没有传实参索引时,sum初始值默认为该数组索引0处的值,item则从该数组索引1处开始循环。

  • 返回值:求的和。

  • 是否修改原数组:不改变。

let arr = [10, 20, 30, 40, 50];
let res = arr.reduce((sum, item, index) => {
      console.log(sum, item, index);
      return sum + item;
})
console.log(res);//150

console.log(sum, item, index);解析
//     sum item index
第一轮:10   20    1
第二轮:30   30    2
第三轮:60   40    3
第四轮:100  50    4
return  150

4.9 reduceRight

  • 作用:一般用于求和。

  • 方向:从右到左循环,倒序。

  • 参数:函数函数有4个形参。

        sum : 和

        item:函数的每一项。

        index:每一项的索引位置。

        array:数组本身

        有传实参时,相当于给sum赋初始值,item则从该数组索引0处开始循环。如果没有传实参索引时,sum初始值默认为该数组索引0处的值,item则从该数组索引1处开始循环。

  • 返回值:求的和。

  • 是否修改原数组:不改变。

let arr = [10, 20, 30, 40, 50];
let res = arr.reduceRight((sum, item, index) => {
	console.log(sum, item, index);
	return sum + item;
})
console.log(res);//150

console.log(sum, item, index);解析
//     sum item index
第一轮:50   40   3
第二轮:90   30   2
第三轮:120  20   1
第四轮:140  10   0
return  150

5. 数组方法总结

5.1 会修改原来数组的方法8个

push(),pop(),shift(),unshift(),reserve(),sort(),splice(),fill()

5.2 删除数组的最后一项的方法3个

数组名.pop( )

数组名.splice( 数组名.length-1, 1)

数组名.length--

5.3 在数组尾部追加内容的方法3个

数组名.push( )

数组名.splice( 数组名.length, 0, 追加的内容)

数组名.[数组名.length]  = 追加的内容;

6. 算法之数组去重

6.1 方法一:数组内部进行比较

        【简单思路实现】:依次拿出数组的中的每一项,和后面的所有项进行比较,如果有相同的就删除。

思路:
第一次:
   拿出数组的第一项:1
                 给[2,3,2,4]进行比较,如果有重复就删除
   拿出数组的第二项:2   
                   ====[3,2,4]进行比较,有重复的删除 [3,4]  
   拿出数组的第三项:3
                   ===4 进行比较,有重复的删除,没有重复
   还用拿最后一项4吗?====不用了                                     
依次拿出数组中的每一项给剩余的所有项进行比较

var ary=[1,2,3,2,4];

function unique(ary){
    for(var i=0;i<ary.length-1;i++){
        var getItem=ary[i];
        for(var j=i+1;j<ary.length;j++){
           var remainItem=ary[j];
           // 如果当前项和后面的项在进行比较的时候,相同就说明重复,要删除掉原数组的那项
           if(getItem==remainItem){
              ary.splice(j,1);
              j--;
           }
        }
   }
   return ary;
}

console.log(unique(ary));

【splice造成的数组塌陷问题】

var ary=[1,2,1,3,3,2,3];


for(var i=0;i<ary.length-1;i++){
    var current=ary[i];
    for(var j=i+1;j<ary.length;j++){
         var next=ary[j];
         if(current==next){
            ary.splice(j,1);
            j--;
         }
    }
}

console.log(ary)

6.2 方法二:利用对象属性名具有唯一性的特点

        【实现的思路】利用对象属性名不重复的思想,先建立一个空对象,然后依次循环数组中的每一项,把此项作为obj对象的属性名和属性值,在添加的时候,如果这个属性名对应的值已经存在,说明此项重复,删除掉此项。

var ary2=[1,2,1,3,3,2,3];

利用对象属性名不能重复的原理:对象中如果没有一个属性的时候就是undefined
把数组中的每一项作为一个对象的属性名和属性值
var obj={1:1,2:2,3:3} 
原理:如果对象属性中已经存在这个属性名,我们就把原数组中此项进行删除


function unique(ary){
   var obj={};
   for(var i=0;i<ary.length;i++){
       var item=ary[i];
       if(typeof (obj[item])!="undefined"){
         //如果此时对象的此属性已经有了,我们就应该删除数组中的那一项
         ary.splice(i,1);
         i--;
         continue;
       }
       obj[item]=item;
   }
   return ary;
}

var ary2=[1,2,1,3,3,2,3];
var res=unique(ary2);
console.log(res);

        【优化方法】:对于数组塌陷,数组中后面所有的数字都要依次改变,这样比较耗性能,怎么优化呢?可以让后面的索引值不变,这样就可以省性能。

  • 把最后一项的值拿过来,占位到塌陷的此项

  • 把最后一项删除

  • 需要注意,此时最后一项也需要比较所以还需要i--;

var ary=[1,2,3,2,3];
var obj={};

for(var i=0;i<ary.length;i++){
   var item=ary[i];
   if(typeof obj[item]!=="undefined"){
        // 把当前重复的项替换成最后一项
        ary[i]=ary[ary.length-1];
        // 最后一项都已经拿过来了,多余,所以删除掉
        ary.length--;
        // 此时占位的这一项(最后一项)还没有比较,所以需要i--,再重新比较一次
        i--;
        continue;
   }
   obj[item]=item;
}

console.log(ary);

6.3 方法三:indexOf

        【实现思路】创建一个新数组,遍历原数组,如果新数组中没有那一项的话,就把它push进去。

  var ary2=[1,2,1,3,3,2,3];
  var newAry=[];
  把原数组中的每一项,只要在新数组中没存在过,我们就把它放进去,最后newAry就是咱们最终要的数组。


function unique(ary){
   var newAry=[];
   for(var i=0;i<ary.length;i++){
       var item=ary[i];
       if(newAry.indexOf(item)==-1){
        newAry.push(item);
       }
   }
   return newAry;
}
var ary2=[1,2,1,3,3,2,3];
var res=unique(ary2);
console.log(res);

7. 算法之冒泡排序

   冒泡排序:
   从小到大排序
   var ary=[8,2,1,5]
   原理:依次拿出数组中的每一项给后面的一项做对比,如果当前项比后面的项大就交换位置
   第一轮:[2,1,5,8] 经过一轮比较出现了最大数
   第二轮:[1,2,5,8] 经过二轮比较得出倒数第2个数
   第三轮:[1,5,2,8]  经过二轮比较得出倒数第3个数
   .... 总共四项,经过比三轮,已经得到了三个最大数了,最后一个自然就是最小数
   【需要比的总轮数】:ary.length-1;
   【每次需要比的次数】:ary.length-1-已经比较过的轮数

   第一轮:4项两两比较需要比3次:ary.length-1
   第二轮: 正常的ary.length-1-已经比较过的轮数

   function sort(ary){
       // 需要比较的轮数
       for(var i=0;i<ary.length-1;i++){
           for(var j=0;j<ary.length-1-i;j++){
              var current=ary[j];
              var next=ary[j+1];
              if(ary[j]>ary[j+1]){
                 // 让 ary[j]=ary[j+1]
                 var temp=ary[j]
                 ary[j]=ary[j+1];
                 ary[j+1]=temp;
                    
              }
           }
       }
       return ary;
   }

   var ary=[8,2,1,5];
   var res=sort(ary);

es6解构赋值

//传统的交换两个数的位置的方法
let a = 10;
let b = 20;
let c;
c = a;
a = b;
b = c; 
console.log(a, b);//a=20;b=10

// es6新增方法:解构赋值
let a = 10;
let b = 20;
[a, b] = [b, a];
console.log(a, b);//a=20;b=10

8. 算法之递归

函数自己调自己就是递归

function fn(num){
  fn(num-1)
}
fn(10)

练习:打印1 到10

// 打印1到10

function fn(num){
    if(num>10){
         return 
    }
    console.log(num); 
    fn(num+1);  
}
fn(1)

9. 递归练习题

9.1 求一个1到100的所有数之和

9.1.1 答案一:普通方法


/* 
  1到100中所有数之和
*/
function total(star,end){
    var total=0;
    for(var i=star;i<=end;i++){
        total+=i;
    }
    return total;
}
var res=total(1,100);
console.log(res);

9.1.2  答案二:递归

function total(num){
   if(num>100){
     return 0;
   }
   return num + total(num+1);
}
total(1)

9.2 [练习题]:求1到100中同时能被2整除又能被3整除的所有数之和

9.2.1  答案一:普通方法

/* 
求1-100所有能被2整除又能被3整除的所有数之和
*/
var total=0;
for(var i=1;i<=100;i++){
    
   if(i%2==0&&i%3==0){
      total+=i;
   }
}
console.log(total);

9.2.2 答案二:递归

function total(num){
   if(num>100){
     return 0;
   }
   if(num%2==0&&num%3==0){
    return  num+total(num+1);
   }
   return total(num+1);
}
var res=total(1);

10. 算法之快速排序

 快速排序:
 var ary=[12,15,14,13,16,11];
 原理:先拿出中间项,然后把此项从数组中删除掉,让数组中的剩余项一一跟这个中间项做比较,新建两个左右数组,如果大的项就放到右盒子,如果小的项就放到左盒子。
 [左盒子小]--中间项--[右盒子大]
 依次再继续重复相同的步骤,把左盒子和右盒子都进行排序,直到出现空数组或者一项的时候停止

 

function quickSort(ary){
    if(ary.length<=1){
        return ary;
    }
   var centerIndex=Math.floor(ary.length/2);
   // 拿到中间项的同时,把中间项从数组中删除掉
   var centerValue=ary.splice(centerIndex,1)[0];
   // 新建两个数组:leftAry,rightAry;把ary中剩余的项,给中间项做对比,如果大项就放到右数组,小项就放到左数组.
   var leftAry=[],rightAry=[];
   for(var i=0;i<ary.length;i++){
        if(ary[i]<centerValue){
            leftAry.push(ary[i]);
        }else{
            rightAry.push(ary[i]);
        }
    }
    return quickSort(leftAry).concat(centerValue,quickSort(rightAry));
}
var ary=[12,15,14,13,16,11];
var res=quickSort(ary);

11. 算法之插入排序

var ary=[34,56,12,66,12];
插入排序:
新建一个数组:依次拿出原数组中的每一项往新数组里面插入,插入的时候需要遵循一个规律:
               1)方向:从右向左
               2)最终实现的效果,从小到大,在插入的时候,拿出的项
               从右向左依次比较(新数组),如果拿出的项大(或者相等),就直接插入首次比它小的后面,
               3)如果一直比到第一项了,条件还没满足,后面就是最小项,直接放到数组的最前面
var newAry=[]
第一次====>我拿出第一项直接放进去,不用进行比较
           newAry=[34]
第二次====> 拿出56 [34,56]          

第三次====> 拿出12 [12,34,56]

第四次=====> 拿出66 [12,34,56,66]

第五次=====> 拿出12 [12,12,34,56,66]

var ary=[34,56,12,66,12];
function insertSort(ary){
   //最终排序好的数组盒子
   var newAry=[];
   //拿出的第一项放进去,此时盒子中只有一项,不用个比较
   newAry.push(ary[0]);
   // 依次拿出原数组中的每一项进行插入
   for(var i=1;i<ary.length;i++){
      var getItem=ary[i];
      // 在插入的时候需要跟新数组中的每一项进行比较(从右向左)
      for(var j=newAry.length-1;j>=0;j--){
           var newItemAry=newAry[j];
           if(getItem>=newItemAry){
             // 如果拿出的项比某项大或者相等,就放到此项的后面
             newAry.splice(j+1,0,getItem);
             // 插入完毕,不用再继续比较停止循环;
             break;
           }
           if(j==0){
            //如果都已经比到第一项了,还没满足条件,说明这个就是最小项,我们之间插入到数组的最前面
            newAry.unshift(getItem);
           }
      }

   }
   return newAry;
}
var res=insertSort(ary)

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值