腾讯的一道面试题,没有答出来,想问问大佬们怎么解答

腾讯云面试的一道笔试题,目前的思路是 for in 这个对象,如果是数组,再 for 循环拿到数组里的对象的属性名

const camelCasedData = {
    age: 18,
    gender: "female",
    experiences: [
        { from: "2009-09", to: "2013-06", exp: "School" },
        { from: "2013-09", to: "2020-02", exp: "Job" },
    ]
};

const camelToPascal = input => {
    // TODO 转json 然后转大小写
    
};
const pascalToCamel = input => {
    // TODO
};

const pascalCased = camelToPascal(camelCasedData);
console.log(pascalCased);
/* 期望输出:
{
    Age: 18,
    Gender: "female",
    Experiences: [
        { From: "2009-09", To: "2013-06", Exp: "School" },
        { From: "2013-09", To: "2020-02", Exp: "Job" },
    ]
}
*/

const camelCasedData2 = pascalToCamel(pascalCased);
// 应该和 camelCasedData 一样

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
参考了各位的答案,自己动手做了一下,做个记录。
思路就是判断值的类型是否为数组,如果是数组,那就遍历一下数组,然后给数组的
每个index的每个属性名称(字符串)做一个首字母转换。

如果不是数组,就直接做属性名称的首字母转换。

        function toUp(str){
            return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()
        }

        function toLow(str){
            return str.toLowerCase()
        }

        function mapTo(e) {
            const newE = {}
            for(key in e){
                const topKey = toUp(key)
                newE[topKey] = e[key]
                if(Array.isArray(e[key])){
                    const topArrKeyName = toUp(key)
                    for(let i = 0;i<e[key].length;i++){
                        const arrObjectKey = e[key][i]
                        newE[topArrKeyName][i] ={}

                        for(key2 in arrObjectKey){
                            const topKey2 = toUp(key2)
                            newE[topArrKeyName][i][topKey2] = arrObjectKey[key2]
                        }

                    }
                }
            }
            return newE
        };
阅读 10.7k
14 个回答

代码内容有待优化~,判断递归的地方

const camelCasedData = {
    age: 18,
    gender: "female",
    experiences: [
        {from: "2009-09", to: "2013-06", exp: "School"},
        {from: "2013-09", to: "2020-02", exp: "Job"},
    ]
};

function toU(str) {
    return str.replace(/\S/, s => s.toUpperCase());
}

function mapTo(obj) {
    const nb = Array.isArray(obj) ? [] : {};

    for (const objKey in obj) {
        const c = obj[objKey];
        if (Array.isArray(c) || Object.prototype.toString.call(c).toLowerCase() === '[object object]') {
            nb[toU(objKey)] = mapTo(c);
        } else {
            nb[toU(objKey)] = c;
        }
    }
    return nb
}

const res = mapTo(camelCasedData)
console.log(res);
/*
{
  Age: 18,
  Gender: 'female',
  Experiences: [
    { From: '2009-09', To: '2013-06', Exp: 'School' },
    { From: '2013-09', To: '2020-02', Exp: 'Job' }
  ]
}
*/

我觉得既然转成了JSON,就没必要再递归遍历了,直接使用正则匹配会更方便。

const camelToPascal = (input) => {
    // TODO 转json 然后转大小写
    let str = JSON.stringify(input);
    str = str.replace(
        /"(\w+)"/g,
        (_, target) => `"${target[0].toLocaleUpperCase() + target.slice(1)}"`
    );
    return JSON.parse(str);
};

笑死, 放弃递归直接正则.

function objectKeyFirstLatterCapital(camelCasedData) {
    let s = JSON.stringify(camelCasedData)
    let i = 0;
    s = s.replace(/"[a-zA-Z]+":/g, () => {
        const arr = s.match(/"[a-zA-Z]+":/g)
        let tempS = arr[i++]
        tempS = tempS.replace(tempS.match(/[a-z]/)[0], tempS.toUpperCase().match(/[a-zA-Z]/)[0])
        return tempS
    })
    return JSON.parse(s)
}

不太会正则 刚研究.
我确实有点菜 😂

const camelCasedData = {
                age: 18,
                gender: "female",
                experiences: [
                    { from: "2009-09", to: "2013-06", exp: "School" },
                    { from: "2013-09", to: "2020-02", exp: "Job" },
                ]
            };

            function transform(str, method) {
                return str.replace(/^(.)(.*)$/, (match, $1, $2) => `${$1[method]()}${$2}`);
            }
            function upper(str) {
                return transform(str, 'toUpperCase');
            }
            function lower(str) {
                return transform(str, 'toLowerCase');
            }

            function change(obj, methodType) {
                if (Array.isArray(obj)) {
                    return obj.map(item => change(item, methodType));
                }
                if (({}).toString.call(obj).toLowerCase() === '[object object]') {
                    return Object.keys(obj).reduce((result, key) => {
                        result[methodType(key)] = change(obj[key], methodType);
                        return result;
                    }, {})
                }
                return obj;
            }

            function camelToPascal(obj) {
                return change(obj, upper)
            }

            function pascalToCamel(obj) {
                return change(obj, lower);
            }

            const d = camelToPascal(camelCasedData);
            console.log(d);
            const e = pascalToCamel(d);
            console.log(e);

这样?

我的思路,递归+判断类型

const camelToPascal = input => {
      if (!(input instanceof Array) && input instanceof Object) {
        let res = {};
        for (let k in input) {
          res[k.replace(k[0], k[0].toUpperCase())] = camelToPascal(input[k]);
        }
        return res;
      } else if (Array.isArray(input)) {
        return input.map(item => camelToPascal(item));
      } else {
        return input;
      }
    };
const pascalToCamel = input => {
  // TODO
  if (!(input instanceof Array) && input instanceof Object) {
    let res = {};
    for (let k in input) {
      res[k.replace(k[0], k[0].toLowerCase())] = pascalToCamel(input[k]);
    }
    return res;
  } else if (Array.isArray(input)) {
    return input.map(item => pascalToCamel(item));
  } else {
    return input;
  }
};
这样子可行?

const camelCasedData = {
    age: 18,
    gender: "female",
    experiences: [
        { from: "2009-09", to: "2013-06", exp: "School" },
        { from: "2013-09", to: "2020-02", exp: "Job" },
    ]
};

const camelToPascal = input => {
    // TODO 转json 然后转大小写
    const json = JSON.stringify(input)
    return json.replace(/(\")([a-z]).*?/g,function(i){
          return i.toUpperCase();
    })
};

const pascalCased = camelToPascal(camelCasedData);
console.log(pascalCased);
*/

判断、递归、修改键头

const camelCasedData = {
    age: 18,
    gender: "female",
    experiences: [
      { from: "2009-09", to: "2013-06", exp: "School" },
      { from: "2013-09", to: "2020-02", exp: "Job" },
    ]
  };
  
  function deepClone(data) {
    let _data = JSON.stringify(data)
    return JSON.parse(_data)
  };

  function toUpper(object) {  //在原数组上修改
    for (const key in object) {
      if (Object.hasOwnProperty.call(object, key)) {
        const element = object[key]
        if (Array.isArray(element)) {  //判断数组或对象再递归
          for (const iterator of element) {
            toUpper(iterator)
          }
        }
        const string = key.replace(/^\w/, str => str.toUpperCase()) //替换键名
        object[string] = element
        delete object[key]
      }
    }
    return JSON.stringify(object)
  }
  let object = deepClone(camelCasedData)
  const camelCasedData1 = toUpper(object )
新手上路,请多包涵
const upperFirst = str => str && String(str.slice(0, 1)).toUpperCase() + str.slice(1)
const lowerFirst = str => str && String(str.slice(0, 1)).toLowerCase() + str.slice(1)
const isObject = obj => Object.prototype.toString.call(obj) == '[object Object]'
const isArray = arr => Array.isArray(arr)
const adapter = (cFn = upperFirst) => (input) => {
  if (!input || !isObject(input) || !Object.keys(input).length) return input
  const res = {}
  const upperObjKeys = (obj, dest) => {
    for (const [k, v] of Object.entries(obj)) {
      dest[cFn(k)] = isArray(v)
        ? v.map(item => adapter(cFn)(item))
        : isObject(v)
          ? upperObjKeys(v, dest[cFn(k)])
          : v
    }
  }
  upperObjKeys(input, res)
  return res
};
const camelToPascal = adapter()
const pascalToCamel = adapter(lowerFirst)

const pascalCased = camelToPascal(camelCasedData);
console.log(JSON.stringify(pascalCased, null, 2));
/* 期望输出:
{
  Age: 18,
  Gender: "female",
  Experiences: [
      { From: "2009-09", To: "2013-06", Exp: "School" },
      { From: "2013-09", To: "2020-02", Exp: "Job" },
  ]
}
*/

const camelCasedData2 = pascalToCamel(pascalCased);
// 应该和 camelCasedData 一样
console.log(JSON.stringify(camelCasedData2, null, 2));

把对象转换为json后对象的key开头会是{“或者,",直接用正则找到换了就行;
转小写把a-z换成A-Z就行了

const camelToPascal = (input) => {
    // TODO 转json 然后转大小写
    const jsonObj = JSON.stringify(input);
    let result = jsonObj.replace(/(?<=(({")|(,")))[a-z]{1}/g, (value) => value.toUpperCase());
    return JSON.parse(result);
};

正则匹配jons字符串 "word": 键中的word,然后转大小写.

const camelCasedData = {
    age: 18,
    gender: "female",
    experiences: [
        { from: "2009-09", to: "2013-06", exp: "School" },
        { from: "2013-09", to: "2020-02", exp: "Job" },
    ]
};

const camelToPascal = input => {
    // TODO 转json 然后转大小写
  let json = JSON.stringify(input);
  let str = json.replace(/((?<=\")\w+":)/g,word=>word.substring(0,1).toUpperCase()+word.substring(1));
    return JSON.parse(str);
  
};
const pascalToCamel = input => {
    // TODO
 let json = JSON.stringify(input);
  let str = json.replace(/((?<=\")\w+":)/g,word=>word.substring(0,1).toLowerCase()+word.substring(1));
    return JSON.parse(str);
};

const pascalCased = camelToPascal(camelCasedData);
console.log(pascalCased);
/* 期望输出:
{
    Age: 18,
    Gender: "female",
    Experiences: [
        { From: "2009-09", To: "2013-06", Exp: "School" },
        { From: "2013-09", To: "2020-02", Exp: "Job" },
    ]
}
*/

const camelCasedData2 = pascalToCamel(pascalCased);
// 应该和 camelCasedData 一样
console.log(camelCasedData2);

输出

//pascalCased
{
    Age: 18,
    Gender: "female",
    Experiences: [
        { From: "2009-09", To: "2013-06", Exp: "School" },
        { From: "2013-09", To: "2020-02", Exp: "Job" },
    ]
}
//camelCasedData2
{
    age: 18,
    gender: "female",
    experiences: [
        { from: "2009-09", to: "2013-06", exp: "School" },
        { from: "2013-09", to: "2020-02", exp: "Job" },
    ]
}

类似深拷贝:

function toUp(str){
    return str[0].toUpperCase() + str.slice(1)
}
function toLow(str){
    return str[0].toLowerCase() + str.slice(1)
}
// 转大写
let camelToPascal = obj => {
    if(typeof obj != 'object') return obj
    let res = {}
    Reflect.ownKeys(obj).forEach(key => {
        res[toUp(key)] = camelToPascal(obj[key])
    })
    return res
}
// 转小写
let pascalToCamel = obj => {
    if(typeof obj != 'object') return obj
    let res = {}
    Reflect.ownKeys(obj).forEach(key => {
        res[toLow(key)] = pascalToCamel(obj[key])
    })
    return res
}

最有开发效率的不是直接用JSON大法吗,还有一堆面试题,这个就没必要动脑筋了,节省下来的时间裸写红黑树。

interface Data {
    [key: string]: Data[] | number | string
}

const camelCasedData: Data = {
    age: 18,
    gender: "female",
    experiences: [
        { from: "2009-09", to: "2013-06", exp: "School" },
        { from: "2013-09", to: "2020-02", exp: "Job" },
    ]
}

const camelToPascal = (input: Data) => {
    const str = JSON.stringify(input)
    //  数字、布尔、lowerCamelCase、NaN、undefined,_,$等都可以作为属性名
    const result = str.replace(/"[a-zA-Z0-9]+":/g,mp => mp.replace(/"[a-z]/,u => u.toUpperCase()))
    return JSON.parse(result)
}

const pascalCased = camelToPascal(camelCasedData)
console.log(pascalCased)
/* 期望输出:
{
    Age: 18,
    Gender: "female",
    Experiences: [
        { From: "2009-09", To: "2013-06", Exp: "School" },
        { From: "2013-09", To: "2020-02", Exp: "Job" },
    ]
}
*/

依赖包:lodash
创作背景:需要将接口返回的json数据中所有的 snakecase 转 camelcase
相似点:所有的key首字母大写

function toUp(str){
    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()
}

const _camelCaseModel = obj => {
  if (obj instanceof Array) {
    _.forEach(obj, i => _camelCaseModel(i))
  } else if (obj instanceof Object) {
    _.forEach(Object.keys(obj), key => {
      const newKey = toUp(key)
      if (newKey !== key) {
        obj[newKey] = obj[key]
        delete obj[key]
      }
      _camelCaseModel(obj[newKey])
    })
  }
  return obj
}

思路:递归,直到最后一层key对应的不是 Object 或 Array

    const camelCasedData = {
      age: 18,
      gender: "female",
      experiences: [{
          from: "2009-09",
          to: "2013-06",
          exp: "School"
        },
        {
          from: "2013-09",
          to: "2020-02",
          exp: "Job"
        },
      ],
      text1: {
        ceshi: 123
      },
      text2: [{
        id: 1,
        name: 'aaa'
      }, {
        id: 2,
        name: '2a'
      }],
      text3: [1, 2, 3, 4],
    };


    function getNeedData(data) {
      let obj = {}
      for (key in data) {
        if (Array.isArray(data[key])) {
          let ary = []
          data[key].forEach(item => {
            let childObj = {}
            if (Object.prototype.toString.call(item) == "[object Object]") {
              for (ckey in item) {
                childObj[ckey.charAt(0).toUpperCase() + ckey.slice(1)] = item[ckey]
              }
              ary.push(childObj)
            } else {
              ary.push(item)
            }
          });
          data[key] = ary
        }
        obj[key.charAt(0).toUpperCase() + key.slice(1)] = data[key]

      }
      return obj
    }
    console.log(getNeedData(camelCasedData))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题