壹题

251 阅读4分钟

1.去重(包括两个[1,2,3]也是重合的)

编程题,根据以下要求,写一个数组去重函数(蘑菇街)

  • new Set(), indexOf都是按引用类型地址去重的
输入:
var arr=[123, "meili", "123", "mogu", 123]
var arr1=[123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"]
var arr2=[123, {a: 1}, {a: {b: 1}}, {a: "1"}, {a: {b: 1}}, "meili"]

输出分别为:
[ 123, 'meili', '123', 'mogu' ]
[ 123, [ 1, 2, 3 ], [ 1, '2', 3 ], 'meili' ]
[ 123, { a: 1 }, { a: { b: 1 } }, { a: '1' }, 'meili' ]

function filterArray(arr) {
  var keys={};
  if(arr&&arr.length){
    var res=arr.filter((item)=>{
      var item=JSON.stringify(item);
      if(!keys[item]){
        keys[item]=true
        return true
      }else{
        return false
      }
    })
  }

2.正则解统计

编程题,找出字符串中连续出现最多的字符和个数(蘑菇街)

  • var str1='abbkejsbcccwqaa' { c: 3 } 3
方法一:
function sameStr(str){
  var arr=str.split('');
  // var map=new Map();
  var obj={};
  var res={};
  for(var i=0;i<arr.length;i++){
    if(arr[i]==arr[i+1]){
      if(!obj[arr[i]]){
        obj[arr[i]]=1;
      }
      obj[arr[i]]++;
    }
  }
  let max=Math.max.apply([],Object.values(obj))
  
  for(var [k,v] of Object.entries(obj)){
    if(v==max){
      res[k]=v;
    }
    
  }
  return res
}

输入:var str='astcdefst' 输出:{ s: 2, t: 2 }

方法二:
function sameStr(str){
  var arr = str1.match(/(\w)\1*/g);// \1表示与前面(\w)一致 [ 'a', 'bb', 'k', 'e', 'j', 's', 'b', 'ccc', 'w', 'q', 'aa' ]
  var arr1=arr.map((item)=>item.length);
  maxLength=Math.max(...arr1);
  const result=arr.reduce((pre,cur)=>{
    if(cur.length==maxLength){
      pre[cur[0]]=cur.length;
    }
    return pre
  },{})
  return result
}


let str = "abcbcbcbbd";
let num = 0;
let char = '';

// 使其按照一定的次序排列
str = str.split('').sort().join(''); //abbbbbcccd
// 定义正则表达式
let re = /(\w)\1*/g;
console.log(str.match(re)); //[ 'a', 'bbbbb', 'ccc', 'd' ]
str=str.replace(re, ($0, $1) => {
  if (num < $0.length) {
    num = $0.length;
    char = $1;
    console.log(num,char);
  }
});
console.log(str,`字符最多的是${char},出现了${num}次`); //字符最多的是b,出现了5次

var str1='1 2 3 4 5 6 7 8'//将>5的数字替换为*
str1=str1.replace(/(\d)/g, function ($0, $1) {
  return $1 = $1>5?'*':$1
})
console.log(str1); //1 2 3 4 5 * * *

//把 "Doe, John" 转换为 "John Doe" 的形式:
var str2 = "Doe, John";
str2=str2.replace(/(\w+), (\w+)/,'$2 $1');
console.log(str2); //"John Doe"

3. 节流 稀释函数执行的频率

// 节流,稀释函数执行的频率
function throttle(fn,wait){
  let canRun=true;
  return function(){
    if(!canRun){
      return 
    }
    canRun=false;
    setTimeout(() => {
      fn.apply(this,arguments);
      console.log(arguments);
      
      canRun=true;
    }, wait);
  }
}

4. 求两个数组的交集

includes,indexof 会有问题,验证[1,1] [1],eg:

function union(nums1,nums2){
  var newArr2 = nums1.filter((item) => {
     return nums2.includes(item);
  });
  console.log(newArr2);
}
出错结果:[1,1]
输入:var nums1 = [1,1],nums2 = [1,2,1,1];
输出:[ 1, 1 ]
function union(nums1,nums2){
  var map={};
  var res=[];
  for (let n of nums1){
    if(map[n]){
      map[n]++
    }else{
      map[n]=1
    }
  }
  console.log(map);           //{ '1': 2 }
  
  for(let n of nums2){
    if(map[n]>0){
      res.push(n);
      map[n]--
    }
  }
  console.log(map);        //{ '1': 0 }
  return res
}

5.将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];

方法一: reduce + 递归
function flat(arr){
  return  arr.reduce((pre,cur)=>{
      var temp=Array.isArray(cur)?flat(cur):[cur];
      pre.push(...temp);
      return pre
    },[])
}
var arrFlat=flat(arr);
var res=[...new Set(arrFlat)].sort((a,b)=>a-b)
console.log(res);//[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]

/**方法二 全是数字的话用toString()  */
function flat(arr){
  var arrFlat=arr.toString().split(',');
  return [...new Set(arrFlat)].map(Number).sort((a,b)=>a-b)
}
/**方法三 while  */
function flat(arr){
  while(arr.some((item)=>Array.isArray(item))){
    arr=[].concat(...arr)
    
  }
  return arr
}

6. 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

var nums = [2, 78,7,11, 15], target = 9;所以返回 [0, 1]

function findIndexArr(arr,target){
  var map=new Map();
  var res=[];
  arr.some((item,index)=>{
    if(map.has(item)){
      res.push(map.get(item),index)
      return true
    }else{
      map.set(target-item,index)
    }
  })
  return res
}
function findIndexArr(arr,target){
  const res=[];
  for(var i=0;i<arr.length;i++){
    const item=target-arr[i];
    const index=arr.indexOf(item,i);
    if(index!=-1){
      res.push(i,index)
    }
  } 
  return res                           
}
console.log(findIndexArr(nums,target));

6.求数组中连续的数

输入 '1,2,3,5,7,8,10'
输出 '1~3,5,7~8,10'

function transformStr(str) {
  let arr=str.split(',');
  let i=0;
  let res=[];
  for(let j=1;j<arr.length;j++){
    if(arr[j]-arr[j-1]!==1){
      res.push(j-i==1?arr[i]:`${arr[i]}~${arr[j-1]}`);
      i=j;
    }
  }
  return res.join(',')
}
console.log(transformStr('1,2,3,5,7,8,10'));

7. 不连续与连续

随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20], // 将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4, 5], [10, 11], [20]]。

  • 不连续
+
[1] 得到一个随机整数,在两数之间[min,max]
function getRandom(min,max){
  min=Math.ceil(min);
  max=Math.floor(max);
  return Math.floor(Math.random()*(max-min+1)) +min//[min,max]之间
}
<!--Array.from ({length:n}, Fn)-->Array.from({length:3}, () => 'jack') //["jack", "jack", "jack"]
<!--第一个参数指定了第二个参数执行的次数。可以将各种值转化为真正的数组。-->

function getNumberArr(length,start,end=100){
  return Array.from({length:length},()=>Math.floor(Math.random()*(end-start+1))+start)
}

var arr=getNumberArr(10,0,20);//乱序长度10,处于[0,20]
var res=formArr(arr)//[0,10],[10,20]各一组
function formArr(arr){
  arr=[...new Set(arr)].sort((a,b)=>a-b);
  const obj={};
  arr.forEach((item)=>{
    const key=Math.floor(item/10);
    if(!obj[key]){
      obj[key]=[];
    }
    obj[key].push(item);
  })
  return Object.values(obj)
}
function formArr(arr){
  arr=[...new Set(arr)].sort((a,b)=>a-b);
  const map=new Map();
  arr.forEach((item)=>{
    const key=Math.floor(item/10);
    const group=map.get(key)||[];
    group.push(item);
    map.set(key,group);
  })
  return  [...map.values()]
}
console.log(formArr([2, 10, 3, 4, 5, 11, 10, 11, 20]));//[ [ 2, 3, 4, 5 ], [ 10, 11 ], [ 20 ] ]

8.手写防抖 节流

  1. 防抖
需要立即防抖的情况

function debounce(fn,immediate,delay){
  var timer=null;
  return function(){
    if (immediate) {
      fn.apply(this, arguments)
    }
    if(timer){
      clearTimeout(timer)
    }
    timer=setTimeout(() => {
      fn.apply(this,arguments)
    }, delay);
  }
}
  1. 节流
利用时间间隔:
function throttle(fn,delay=500){
  var startTime=new Date();
  return function(){
    var now=new Date();
    if(now-startTime>delay){
      fn.apply(this,arguments);
      startTime=new Date()
    }
  }
}

利用定时器
function throttle(fn, delay=500) {
  var canRun=true;
  return function(){
    if(!canRun) return ;
    canRun=false;
    setTimeout(() => {
      fn.apply(this)
      canRun=true;
    }, delay);
  }
}

9. promise封装一个ajax

function ajax(url){
  return new Promise((resolve,reject)=>{
    const xhr=new XMLHttpRequest();
    xhr.open('GET',url,true);
    xhr.send();
    xhr.onreadystatechange=function(){
      if(xhr.status=200&&xhr.readyState==4){
        resolve(JSON.parse(xhr.responseText))
      }else{
        const reason={code:xhr.status,message:this.response}
        reject(reason)
      }
    }
  })
}