实现react的classnames | 刷题打卡

199 阅读1分钟

题目描述

实现 react 的 classname 题目链接:BFE.dev 题干如下: 题干截图

思路分析

把参数转化成空格连接的字符串,参数类型除 null, undefined, Symbol(), 1n, true, false 以外,例如题干中的:

const obj = new Map();
obj.cool = '!';

expect(classnames('BFE', 'DEV', 100)).toEqual('BFE DEV 100');
expect(classNames({ BFE: [], dev: true, is: 3 }, obj)).toEqual('BFE DEV is cool');
expect(classNames(['BFE', [{dev: true}, ['is', [obj]]]])).toEqual('BFE DEV is cool');
  • 把入参拍平,希望拍平后的参数 => ('BFE', 100, {name: 'xxx'}, {name: 'xxx', age: 18})
  • 处理参数并添加到新队列 string & number 类型直接添加,object 类型添加值

AC代码

function classNames(...args) {
    // your code here
    args = flatten(args);
    return args.reduce((memo, arg) => {
        if (typeof arg === 'string' || typeof arg === 'number') {
            memo.push(arg);
        } else if (typeof arg === 'object') {
            const result = Object.keys(arg).reduce((arr, key) => {
                if (!!arg[key]) {
                    arr.push(key);
                }
                return arr;
            }, []);
            memo.push(...result);
        }
        return memo;
    }, []).join(' ');
}

function flatten(args) {
  return args.reduce((memo, arg) => {
    if (arg instanceof Array) {
      memo.push(...arg.flat(Infinity));
    }
    else {
      memo.push(arg);
    }

    return memo;
  }, []);
}

总结

写完之后,我去看了下 classnames 源码,区别在于 flatten 合并在了 parse 阶段递归运算再把结果添加到新队列:

if (Array.isArray(arg)) {
  if(arg.length) {
      var inner = classNames.apply(null, arg);
      if (inner) {
          classes.push(inner);
      }
  }
}

周末加班之余写的,后面会挑一点有难度的题~
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情