前端常用方法以及算法

132 阅读2分钟

谨记录项目中遇到的方法以及算法

防抖节流

  // 防抖
  function debounce(fn,delay){
     let timer= null
     return function(){
       if(timer)clearTimeout(timer)
       timer = setTimeout(()=>{
       fn.apply(this,[...arguments])
       },delay)
     }
  }
  // 节流
  function throttle(fn,delay){
     let startTime = new Date().getTime()
      return function (){
        let endTime = new Date().getTime()
        if(delay<endTime-startTime){
          fn.apply(this,[...arguments])
           startTime = endTime
         }
      }
   }

字符串转成3位金额逗号隔开或n位隔开格式

function translate(str){
return str.split('').reverse().join('').replace(/(\w{3})/g,(n)=>n+',').split('').reverse().join('').replace(/^,/,'')
}

字符串下划线_驼峰相互转换

// 下划线转驼峰
function underlineToHump(str){
return str.replace(/_(\w)/g,(n,l)=>l.toUpperCase())
}
// 驼峰转下划线
function humpToUnderline(str){
 return str.replace(/([A-Z])/g,(n)=>'_'+n.toLowerCase())
}

冒泡、归并、快排三种排序方式(算法)

  // 冒泡排序--时间复杂度 O(n^2)
 function bubbleSort(arr) {
  for(let i=0;i<arr.length-1;i++){
   for(let j=i+1;j<arr.length;j++){
    if(arr[i]>arr[j]){
      [arr[i],arr[j]]=[arr[j],arr[i]]
     }
    }
  }
 }
 // 归并排序--时间复杂度 O(cnlogn+cn)
 function mergeSort(arr){
     if(arr.length<=1){
      return arr 
     }
     let midIndex = Math.floor(arr.length/2)
     let mid = arr.splice(midIndex,1)[0]
     let left = []
     let right = []
     arr.forEach((item)=>{
      if(item<mid){
        left.push(item)
      } else {
       right.push(item)
      }
   })
  return [...mergeSort(left),mid,...mergeSort(right)]
 }
 //快速排序--时间复杂度 最好O(n) 最差O(n^2) 平均O(nlogn)
 function quickSort(arr,left=0,right=arr.length-1){
     if(left>=right){
      return arr
     }
     let base = arr[left]
     let i = left 
     let j = right
     while(j>i){
      while(j>i&&arr[j]>=base){
            j--
      }
      while(j>i&&arr[i]<=base){
            i++
      }
      if(j>i){
            [arr[i],arr[j]]=[arr[j],arr[i]]
      }
      [arr[left],arr[j]] = [arr[j],arr[left]]
      quickSort(arr,left,j-1)
      quickSort(arr,j+1,right)
      return arr 
}
 
 }

深度优先遍历递归版(算法)

function dsf(root){
 let arr = [...root]
 arr.forEach((element)=>{
  //do somethings
  //...
  element.children&&element.children.length&&dsf(element.children)
 })
}

深度优先遍历非递归版(算法)

function dsf(root){
  let stack = [..root];
  while(stack.length){
    let pop = stack.pop()
    //do somethings
    //...

    let children = pop.children
    if(children&&children.length){
    let i = children.length
     while(i){
      i--
      stack.push(children[i])
     }
    }
 }
}

广度优先遍历(算法)

function bsf(root){
  let queue = [...root]
  while(queue.length){
    let shift = queue.shift()
    //do somethings
    //...

    shift.children&&shift.children.length&&queue.push(...shift.children)
  }
}

将平铺数组通过id->pid转化树结构

//[{id: 1,pid: 0,name: '1'}, {id: 2,pid: 1,name: '1-1'}, {id: 3,pid: 2,name: '1-1-1'},{id: 4,pid: 2,name: '1-1-2'}, {id: 5,pid: 1,name: '1-2'}, {id: 6,pid: 0,name: '2'}, {id: 7,pid: 6,name: '2-1'}]

function flatArrToTree(arr,pid){
 // 如果pid 不存在则寻找pid
 if(!pid){
   for(let i=0;i<arr.length;i++){
    let _pid = arr[i].pid
    if(arr.filter(d=>d.id===_pid)){
     pid =_pid
    }
   }
 }
 let tree = []
 arr.forEach(element=>{
 if(element.pid===pid){
   let children = flatArrToTree(arr,element.id)
   if(children.length){
   element.children = children
   }
   tree.push(element)
  }
 })
 return tree
}

将树结构通过字段检索返回一个新的树递归版

// 这里通过name 字段搜索
function searchName(tree,name){
 let newTree = []
 tree.forEach((element)=>{
    if(element.children&&element.children.length){
        // 如果当前节点包含该搜索字段,则将整个父节点推入数组
        if(element.name.includes(name)){
          newTree.push({...element})
        }else {
         let children= searchName(element.children,name)
         if(children.length){
         let o = {
            ...element,
            children
           }
           newTree.push(o)
         }
        }
    }else {
     element.name.includes(name)&&newTree.push({...element})
  }
 })
 return newTree
}

将数组转化成链表结构(算法)

 // arr = ['a','b','c','d'] 返回 {value:'a',next:{value:'b',next:{value:'c',next:{value:'d'}}}} 
 function arrToLink(arr){
 if(arr.length<=1) return {value:arr[0]}
  let head = {
   value:arr[0]
  }
  let o = head
  for(let i=1;i<arr.length;i++){
   let no = {
     value:arr[i]
    }
    o.next = no 
    o=no
  }
  return head
 }

反转链表(算法)

//{value:'a',next:{value:'b',next:{value:'c',next:{value:'d'}}}}=>{value:'d',next:{value:'c',next:{value:'b',next:{value:'a'}}}}
function reverseLink(head){
  let cur= head
  let pre = null
  let next = null
  while(cur){
    next = cur.next
    cur.next = pre
    if(!pre) delete cur.next
    pre = cur
    cur = next 
 }
 return pre
}

字符串全排列(算法)

// 'abc'->["abc", "bac", "bca", "acb", "cab", "cba"]
 function wArrange(str){
  if(str.length===1)return [str]
  if(str.length===2)return [str[0]+str[1],str[1]+str[0]]
  let s = str.substr(0,1)
  let e = str.substr(1)
  let r = wArrange(e)
  let arr = []
  r.forEach((element)=>{
   for(let i =0;i<=element.length;i++){
    arr.push(element.substr(0,i)+s+element.substr(i))
   }
  })
  return arr 
 }

Promise 最大并发限制 ( 有n个请求, 每次只能并发请求m个,直到n个请求全部完成)

/****模拟request请求 start***/
let createFetch = function (i) {
  return function () {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(`请求${i}完成`)
      }, 2000 * Math.random())
    })
  }
}
//请求接口数组 模拟了17个请求
let fetchs = []
for (let i = 0; i < 17; i++) {
  fetchs.push(createFetch(i))
}
/****模拟request请求 end***/

function maxConcurrency(https,max){
  // 首次填充请求数组
  let firstArr = https.slice(0,max)
  // 剩余请求
  let left = https.slice(max)
 //正在请求数组
 let current = []
 // 发起请求
 function start(htp){
  let promise = htp()
  current.push(promise)
  promise.then((res)=>{
    console.log(res)
    console.log('当前正在请求数量:',current.length)
    current.splice(current.findIndex(v=>v==promise),1)
    let newHtp = left.shift()
    if(newHtp){
     start(newHtp)
    }
 })
} 
}
//调用方式,最大并发数量为5个
maxConcurrency(fetchs,5)