前端笔试题

前端笔试题

/**
* 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。
* 返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。
* 可以不考虑输出结果的顺序。
*
* 输入:nums1 = [1,2,2,1], nums2 = [2,2]
* 输出:[2,2]
*
* 输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
* 输出:[4,9]
*/

const nums1 = [1,2,2,1], nums2 = [2,2,1, 2, 2]
function intersect(nums1, nums2) {
  let map = new Map(), arr = [], len1 = nums1.length, len2 = nums2.length
  for (let a = 0; a < len1; a++) {
    if (map.has(nums1[a])) {
      map.set(nums1[a], map.get(nums1[a]) + 1)
    } else {
      map.set(nums1[a], 1)
    }
  }

  for (let a = 0; a < len2; a++) {
    if (map.has(nums2[a]) && map.get(nums2[a]) > 0) {
      arr.push(nums2[a])
      map.set(nums2[a], map.get(nums2[a]) - 1)
    }
  }
  return arr
};

const result = intersect(nums1, nums2)
console.log(result)
/**
 * 已知如下数组:var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
 * 编写一个函数将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
 */
// 方式一:
const arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
const s = new Set()
function arrHandle(arr) {
  if (Array.isArray(arr)) {
    arr.forEach(children => {
      arrHandle(children)
    })
  } else {
    s.add(arr)
  }
}
arrHandle(arr)
const result = [...s].sort((a, b) => a - b)
console.log(result)

// 方式二:
console.log(Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b}))
/**
 * 设计 LazyMan 类,实现以下功能
 * LazyMan('Tony');
 * // Hi I am Tony
 * 
 * LazyMan('Tony').sleep(10).eat('lunch');
 * // Hi I am Tony
 * // 等待了10秒...
 * // I am eating lunch
 *
 * LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
 * // Hi I am Tony
 * // I am eating lunch
 * // 等待了10秒...
 * // I am eating diner
 * 
 * LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
 * // Hi I am Tony
 * // 等待了5秒...
 * // I am eating lunch
 * // I am eating dinner
 * // 等待了10秒...
 * // I am eating junk food
 */
 
// 实现
class LazyMain {
  constructor(name) {
    this.name = name
    console.log(`Hi I am ${this.name}`)
    this.callbacks = []
  }

  eat(food) {
  	// 订阅
    this.callbacks.push(() => console.log(`I am eating ${food}`))
    // 加入微任务在同步代码执行完毕后执行
    process.nextTick(() => {
      const fn = this.callbacks.shift()
      fn && fn()
    })
    return this
  }

  sleep(delay) {
    const newDate = Date.now()
    while((Date.now() - newDate) / 1000 < delay){}
    return this
  }

  sleepFirst(delay) {
    this.sleep(delay)
    // 发布
    this.callbacks.forEach(fn => fn())
    this.callbacks = []
    return this
  }
}

const lazyMain = new LazyMain('Tony')
lazyMain.eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food')

// 执行结果
// Hi I am Tony
// I am eating lunch
// I am eating dinner
// I am eating junk food
/**
 * 模拟实现发布订阅模式
 */
class Observe {
  constructor() {
    this.message = {};
  }
  $on(type, fn) {
    this.message[type]
      ? this.message[type].push(fn)
      : (this.message[type] = [fn]);
  }
  $off(type, fn) {
    if (!this.message[type]) return;
    if (!fn) {
      this.message[type] = undefined;
    } else {
      console.log("else");
      this.message[type] = this.message[type].filter((el) => el != fn);
    }
  }
  $emit(type) {
    if (!this.message[type]) return;
    this.message[type].forEach((el) => {
      el();
    });
  }
}
const person1 = new Observe();

function handler1() {
  console.log("handler1");
}
function handler2() {
  console.log("handler2");
}
person1.$on("abc", handler1);
person1.$on("abc", handler2);
person1.$emit("abc");
console.log(person1.message);

// 执行结果
// handler1
// handler2
// { abc: [ [Function: handler1], [Function: handler2] ] }
/**
 * 以下数据结构中,id 代表部门编号,name 是部门名称,parentId 是父部门编号,为 0 代表一级部门,
 * 现在要求实现一个 convert 方法,把原始 list 转换成树形结构,parentId 为多少就挂载在该 id 的属性 children 数组下,结构如下:
 * 原始 list 如下
    let list =[
        {id:1,name:'部门A',parentId:0},
        {id:2,name:'部门B',parentId:0},
        {id:3,name:'部门C',parentId:1},
        {id:4,name:'部门D',parentId:1},
        {id:5,name:'部门E',parentId:2},
        {id:6,name:'部门F',parentId:3},
        {id:7,name:'部门G',parentId:2},
        {id:8,name:'部门H',parentId:4}
    ];
    转换后的结果如下
    let result = [
        {
          id: 1,
          name: '部门A',
          parentId: 0,
          children: [
            {
              id: 3,
              name: '部门C',
              parentId: 1,
              children: [
                {
                  id: 6,
                  name: '部门F',
                  parentId: 3
                }, {
                  id: 16,
                  name: '部门L',
                  parentId: 3
                }
              ]
            },
            {
              id: 4,
              name: '部门D',
              parentId: 1,
              children: [
                {
                  id: 8,
                  name: '部门H',
                  parentId: 4
                }
              ]
            }
          ]
        },
      ···
    ];
 */

let list =[
  {id:1,name:'部门A',parentId:0},
  {id:2,name:'部门B',parentId:0},
  {id:3,name:'部门C',parentId:1},
  {id:4,name:'部门D',parentId:1},
  {id:5,name:'部门E',parentId:2},
  {id:6,name:'部门F',parentId:3},
  {id:7,name:'部门G',parentId:2},
  {id:8,name:'部门H',parentId:4}
];
// 方式一:
function test(list) {
    let res = []
    // 按id对Object分类
    let maps = list.reduce((pre, cur) => { pre[cur.id] = cur; return pre }, {})
    // let maps = new Map(Array.from(list, (x) => [x.id, x]))
    console.log('maps', maps)
    for(let i = 0, len = list.length; i < len; i++ ) {
        let item = list[i]
        if(item.parentId === 0) {
            res.push(item)
        } else {
            let parent = maps[item.parentId]
            // let parent = maps.get(item.parentId)
            parent.children = parent.children || []
            parent.children.push(item)
        }
    }
    return res
}
let res = test(list)
console.log(res)

// 方式二:
function buildTree(list, parentId) {
  const tree = [];
  for (let i = 0; i < list.length; i++) {
    if (list[i].parentId === parentId) {
      const node = {
        id: list[i].id,
        name: list[i].name,
        children: buildTree(list, list[i].id)
      };
      tree.push(node);
    }
  }
  return tree;
}

const tree = buildTree(list, 0);
console.log(tree);
// 如果有100个请求,你如何使用Promise控制并发?
const arr = [];
for (let i = 0; i < 100; i++) {
  arr.push(
    () =>
      new Promise((resolve) => {
        setTimeout(() => {
          console.log("done", i);
          resolve();
        }, 100 * i);
      })
  );
}

const parallelRun = () => {
  const runingTask = new Map();
  const inqueue = (totalTask, max) => {
    while (runingTask.size < max && totalTask.length) {
      const newTask = totalTask.shift();
      const tempName = totalTask.length;
      runingTask.set(tempName, newTask);
      newTask().finally(() => {
        runingTask.delete(tempName);
        inqueue(totalTask, max);
      });
    }
  };
  return inqueue;
};

parallelRun()(arr, 6);

持续更新中~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值