一维数组:数组中只有一级
二维数组:数组中有两级
多维数组:数组中有两级及以上
变成一维数组的操作——扁平化
es6中新增的方法
ps.不知道的api找mdn
去重
对象键值对
新开一个数组 for循环 indexOf includes来判断
new Set来去重
……
经典算法
思路:将数组变为字符串
toString是会把一个数组直接变为一个字符串,字符串里绝对不会出现中括号[],而把每项用逗号, 分隔;
toString会自动扁平化,以逗号连接
这里扩展一下Object.prototype.toString.call({name:'angela',age:18})
Object.prototype.toString() - Javascript | MDN
join也是一样的
ps.map改变每项的值,返回啥就改成啥
stringify和toString的区别在于 stringify是有中括号的
let arr=[1,2,[3,8],[35,87,[26,9]]]
let arr1=[{name:'angela',age:18},{name:'tom',age:18}]
// 1.flat方法
console.log('1.flat方法--------------------')
console.log(arr.flat(Infinity));
// 2.toString和join
console.log('2.toString和join--------------------')
console.log(arr.toString().split(',').map(i=>Number(i)));
console.log(arr.join().split(',').map(i=>Number(i))); // join同toString是一样
console.log(arr1.flat(Infinity));
console.log(arr1.toString().split(',')); // 有局限的
console.log(arr.join('|').split(/,|\|/g)); // 有局限的
// 3.JSON.stringify
console.log('3.JSON.stringify--------------------')
console.log(JSON.stringify(arr).replace(/\[|\]/g,'').split(','))
console.log(JSON.stringify(arr1).replace(/\[|\]/g,''));
前言:
用函数制定一个规则,检测数组中的某一项是否符合这个规则
some做检测
ps.forEach map some find
Array.isArray手动改原型链依然判为false 检测数据类型
...arr:每次只展开一级,展开不了很深
// 4.concat(...arr)
console.log('4.concat(...arr)--------------------')
console.log([].concat(...arr))
while(arr.some(i=>Array.isArray(i))){
arr=[].concat(...arr)
}
console.log(arr);
递归思路:
fn执行的时候又调了自己
循环当前这个数组的每一项:
不是数组,创建一个新数组存起来;
当前是数组,再调这个方法(先不管这个),重新进来
// res放在外面
let res=[]
function deep(arr){
for(let i=0;i
if(arr[i] instanceof Array){
deep(arr[i]);
continue;
}
res.push(arr[i])
}
}let arr=[1,2,[3,8],[35,87,[26,9]]]
deep(arr);
console.log(res);
// res放在里面
function myFlatter(arr){
let res=[]
arr.forEach(i=>{
if(Array.isArray(i)){
res=res.concat(myFlatter(i))
}else{
res.push(i)
}
})
return res;
}
res=myFlatter(arr);
console.log(res);
function flatter(arr){
return arr.reduce((total,i)=>{
// if(Array.isArray(i)){
// total=total.concat(flatter(i));
// }else{
// total.push(i)
// }
// return total;
return Array.isArray(i)?total.concat(flatter(i)):[...total,i]
},[])
}
res=flatter(arr);
console.log(res);
Javascript数组扁平化的五种方式_二九君的博客-CSDN博客_Javascript数组扁平化
【Javascript】实现数组扁平化_程序媛小y的博客-CSDN博客_js数组扁平化处理
作为构造函数执行的步骤:
扩展一下Object.create
+创建一个空对象
+该对象的__proto__指向你传的参数(它所属构造函数的实例)。合理下传入的应该是一个原型对象proto,那么创建出来的空对象就是proto所属构造函数(该proto的constructor指向)的实例。
这里有一点绕口令:
Fn.prototype属于哪个构造函数的原型?Fn
function Dog(name){
this.name=name;
}
Dog.prototype.bark=function(){
console.log('wang wang')
}
Dog.prototype.sayName=function(){
console.log('my name is' + this.name);
}let sanmao=new Dog('sanmao');
console.dir(sanmao);// function _new(Dog,name){
// const obj={};
// obj.name=name;
// obj.__proto__=Dog.prototype;
// return obj;
// }
function _new(Fn,...args){
// let obj={}
// obj.__proto__=Fn.prototype;
let obj=Object.create(Fn.prototype);
Fn.call(obj,...args);
return obj;
}
sanmao=_new(Dog,'liumao')
console.dir(sanmao);
数组合并concat
(function(){
let arr1=['A1','A2','B1','B2','C1','C2','D1','D2']
let arr2=['A','B','C','D'] let arr=[]
for(let i=0;i
if(arr1[i][0]
let alpha=arr2.find(item=>item===arr1[i][0])
alpha?arr.push(arr2.shift()):null;
continue;
}
arr.push(arr1[i]) } if(arr2.length){
// 如果原来数组是乱序的这里还得改一下
arr=arr.concat(arr2);
} console.log(arr);
console.log(arr1);
console.log(arr2);
})()function method2(){
let arr1=['A1','A2','B1','B2','C1','C2','D1','D2']
let arr2=['A','B','C','D'] let arr=[]
arr2.forEach((alpha)=>{
let index=arr1.findLastIndex(i=>i[0]===alpha)
arr1.splice(index+1,0,alpha);
})
console.log(arr);
console.log(arr1);
console.log(arr2);
}
method2();
let形成块级作用域。当前i的值存在当前块级作用域里,定时器回调触发的时候找的i是当前块级作用域中的i
循环体里面整个是一个大函数,保存变量i
for(var i=0;i<10;i++){
(function(i){
// i为参数
setTimeout(()=>{
console.log(i)
},1000)
})(i)}
另一种思路是在setTimeout的回调做文章,这里也是一个函数
for(var i=0;i<10;i++){
// setTimeout((function(i){
// return ()=>console.log(i)
// })(i),1000)
// return一个function是在这里做文章
setTimeout(((i)=>()=>console.log(i))(i),1000)}
function timer(){
return i=>{
setTimeout(()=>console.log(i),1000)
}
}
思路一样,使用bind
for(var i=0;i<10;i++){
var fn=function(i){
console.log(i)
}
setTimeout(fn.bind(null,i),1000)}
匿名函数如果设置了函数名
外面反而不能用,里面是能用的
里面AAA就相当于是一个const变量,
你改这个值是没有效果的,但是它不会报错(非strict)
但是你前面加了var,本身这个函数名就失效了
设置了名字带来的问题:
外面不能用,里面用了还不能改
当一个变量前没有var let const,沿着上级作用域链查找
两个等号叫比较
三个等号叫绝对比较
(一个等号叫赋值)
==:若数据类型不一样,先转换成一样的再进行比较
===:类型一样值也一样
var a={
i:0,
valueOf:function(){
this.i++;
console.log(this.i);
return this.i;
},
[Symbol.toPrimitive]:function(){
return ++this.i;
}
}
console.log(a==1)
这道题思路:
number类型不可能,bool也不行,字符串……
Array.prototype.toString 以逗号连接数组中的每一项
Object.prototype.toString 用来检测数据类型的
所属类原型上的方法
对某个属性的描述,设置某个属性的相关特征
参数:对象 键 描述符
获取这个属性的时候,就会走get函数
// 简单版
let n=0;
Object.defineProperty(window,&#39;a&#39;,{
get(){
return ++n;
}
})
if(a==1 && a==2 & a==3){
console.log(&#39;OK&#39;)
}
Object.defineProperty(window,&#39;a&#39;,{
get(){
// 这时的this代表这个属性
this.value?this.value++:this.value=1;
return this.value;
}
})
if(a==1 && a==2 & a==3){
console.log(&#39;OK&#39;)
}
冒泡:越大的气泡越在上。
当前项和后一项进行比较,最大的排在后面
动图效果:
1662627592813.mp4
引申一下:交换
外层循环控制比较的轮数,n个数我只需要比较n-1次,因为我只需要把n-1个数依次放到末尾;
内层循环控制每轮要比较的次数,
整体思路:
外循环控制多少轮,里层循环控制比较次数,不用跟自己比,做多length-1,然后减掉末尾的数;
将抓入的牌依次和手里的牌进行比较;
从后往前看,手上的牌小了,就往前挪;大了就插过去
let arr=[9,16,28,18,98,63,3];
for(let i=1;i
// arr[i]:要插入的元素
let insert=arr[i]
let j=i-1;
for(;j>=0;j--){
// 插入的数大于(等于)比较的元素 j+1
if(insert>=arr[j]){
// j+1 -> i-1 往后挪
for(let p=i-1;p>=j+1;p--){
arr[p+1]=arr[p];
}
arr[j+1]=insert;
break;
}
}
// 出循环没插入
if(j<0){
// 0 -> i-1 往后挪
for(let p=i-1;p>=0;p--){
arr[p+1]=arr[p];
}
arr[0]=insert;
}
}
console.log(arr);
let arr=[9,16,28,18,98,63,3];
for(let i=1;i
// arr[i]:要插入的元素
let insert=arr[i]
let j=i-1;
for(;j>=0;j--){
// 插入的数大于(等于)比较的元素 j+1
if(insert>=arr[j]){
// 用splice一定要先删除再插入// 这里删除的位置一定大于插入的位置,所以不会产生数组塌陷
arr.splice(i,1);
arr.splice(j+1,0,insert)
break;
}
}
// 出循环没插入
if(j<0){
// 用splice一定要先删除再插入
arr.splice(i,1);
arr.splice(0,0,insert)
}
}
console.log(arr);
或者就像视频中新开一个数组,视频中的方法是新开一个数组
https://www.jianshu.com/p/bd0ed19bc158
Javascript插入排序 - 帕图纳克斯 - 博客园
js 实现排序算法 -- 插入排序(Insertion Sort)
网上很多是这样:
let arr=[9,16,28,18,98,63,3];
for(let i=1;i
// arr[i]:要插入的元素
let insert=arr[i]
let j=i-1;
while(j>=0 && insert
arr[j+1]=arr[j];
j--;
}
arr[j+1]=insert; }
console.log(arr);
自己总结:
插入排序其实就是抓牌,将新的牌与手中已有的牌进行比较,从后往前比,当新的牌大于(等于)当前比较的元素时,这个时候插入进去。
所以代码上是:
首先取0号位置作为已排序数组,所以外层循环从1号位置开始循环,i=1;i
从后往前扫描,j=i-1;并且用一个变量temp保存这张新牌即arr[i],从后往前扫描的同时元素依次往后挪,边比较边往后挪,内层循环的条件是 while j>=0 && temp
思路:
let arr=[18,24,56,90,3,7,65]
function quick(arr){
let i=Math.floor(arr.length/2);
let middle=arr[i];
arr.splice(i,0);
let left=[],right=[];
arr.forEach(item=>{
if(item
if(item>=middle) right.push(item)
}) if(left.length>=1) left=quick(left);
if(right.length>=1) right=quick(right)
return left.concat(middle).concat(right)}console.log(quick(arr));
Javascript 实现快速排序 - 知乎
快速排序(Quicksort)的Javascript实现 - 阮一峰的网络日志
diff算法 阮一峰_Javascript实现十大排序算法_短腿胖胖小笨猪的博客-CSDN博客
自己总结:
首先在数组中选一个元素作为基准点,比如一般选中间值,比这个值小的都放到左边,比这个值大的都放到右边,然后分别对左边和右边依次递归,最后返回的是左中右的拼接。
一门语言:
语法本身,设计模式,底层原理,框架,服务器部署,数据库;
这3个排序是入门级别的,二叉树&三叉树,
let obj={
1:22,
2:333,
12:878,
}let arr=new Array(12).fill(null);
arr.forEach((i,index)=>{
obj[index+1]?arr[index]=obj[index+1]:null;
})
// 这里用map会更好
arr=new Array(12).fill(null).map((_,index)=>{
return obj[index+1] || null;
})
console.log(arr);
map改变之前的值
let obj={
1:22,
2:333,
12:878,
}obj.length=13;
arr=Array.from(obj).slice(1).map(i => i || null)
console.log(arr);
注意一下重复元素的情况
let arr1=[1,2,2,76,39,22];
let arr2=[2,39,67,36];
let arr=arr1.reduce((total,item)=>{let index=arr2.indexOf(item)if(index>-1){
arr2.splice(index,1)
total.push(item);}return total;
},[])
console.log(arr);
思考题:交差并补
k写几就是把最后几位放前面
方法一:slice支持负数作为索引
方法二:splice返回删除的数组
方法三:pop unshift
数组切割再拼接
let arr=[1,2,3,4,5,6,7,8]
function rotate(arr,k){
let length=arr.length;
k=k%length;
arr=arr.map((value,index)=>{
return {
value,
index:(index+k)%length
}
})
arr.sort((a,b)=>{
return a.index-b.index;
})
arr=arr.map(i=>(i.value))
return arr;}arr=rotate(arr,3);
console.log(arr);
比较简单的做法,这样也行
function add(n1,n2,n3){return n1+n2+n3;
}
function currying(...args){if(args.length>=3){return add(...args)}return (...arg)=>{return currying(...args,...arg);}
}
console.log(currying(1,2)(3))
console.log(currying(1)(2,3))
console.log(currying(1)(2)(3))
console.log(currying(1,2,3))
call & apply & bind 与柯理化