添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account
  const changeKey = (obj) => {
    let objValueKey = [obj];
    while (objValueKey.length) {
      objValueKey.forEach((item, index) => {
        objValueKey.splice(index, 1);
        for (let item2 in item) {
          if (Object.prototype.toString.call(item[item2]) === "[object Object]") {
            objValueKey.push(item[item2]);
          item[item2.replace(/_/, "")] = item[item2];
          delete item[item2];
      });
    return obj;
  const a = {
    a_y: {
      a_z: {
        y_x: 6
      b_c: 1
  console.time('耗时');
  console.log(changeKey(a));
  console.timeEnd('耗时');
[ K in keyof T ] : DeepTypeOrString < T [ K ] > ; type Recursion = < T > ( obj : DeepTypeOrString < T > ) => DeepTypeOrString < T > ; const recursion : Recursion = ( obj ) => { const keys = Object . keys ( obj ) ; keys . forEach ( ( key ) => { const newKey = key . replace ( / _ / g , "" ) ; obj [ newKey ] = recursion ( obj [ key ] ) ; delete obj [ key ] ; } ) ; return obj ; console . log ( recursion ( a ) ) ;

方法二:序列化 JSON.stringify + 正则匹配

type DeepTypeOrString<T> = {
  [K in keyof T]: DeepTypeOrString<T[K]>;
type RegularExpress = <T>(obj: DeepTypeOrString<T>) => DeepTypeOrString<T>;
const regularExpress: RegularExpress = (obj) => {
  try {
    const regExp = /_/g;
    const str = JSON.stringify(obj).replace(regExp, "");
    return JSON.parse(str);
  } catch (error) {
    return obj;
};;
const obj = { } ; for ( let i in data ) { let key = ` ${ i . slice ( 0 , 1 ) } ${ i . slice ( 2 , 3 ) } ` ; if ( data [ i ] instanceof Object ) { obj [ key ] = dfs ( data [ i ] ) ; } else { obj [ key ] = data [ i ] ; return obj ; const a = { a_y : { a_z : { y_x : 6 b_c : 1 console . log ( dfs ( a ) ) ; // { ay: { az: { yx: 6 }, bc: 1 } } // 方法2 迭代 function dfs ( data ) { let arr = [ data ] ; while ( arr . length != 0 ) { const target = arr . pop ( ) ; change ( target ) ; // 对对象里的数据进行名称转化 if ( target instanceof Object ) { // 如果是对象的话,继续将他的属性加进去 for ( let i in target ) { arr . push ( target [ i ] ) ; console . log ( data ) ; return data ; const change = ( data ) => { const key = Object . keys ( data ) ; const reg = / \_ / g ; for ( let i = 0 ; i < key . length ; i ++ ) { let tempKey = key [ i ] . replace ( reg , '' ) ; data [ tempKey ] = data [ key [ i ] ] ; delete data [ key [ i ] ] ; const a = { a_y : { a_z : { y_x : 6 , z_j : 7 , b_c : 1 dfs ( a ) //{ ay: { az: { yx: 6, zj: 7 }, bc: 1 } } try { const reg = / (\w+)_(\w+)": / g return JSON . parse ( JSON . stringify ( obj ) . replace ( reg , ( match ) => match . replace ( '_' , '' ) ) ) } catch ( error ) { return obj console . log ( parseKey ( a ) ) if ( ! obj ) return for ( let key in obj ) { if ( typeof obj [ key ] === 'object' && obj [ key ] !== null ) { list . push ( obj [ key ] ) dfs ( obj [ key ] , list ) return list function transformKeys ( obj ) { const list = [ ] dfs ( obj , list ) list . forEach ( item => { for ( let key in item ) { const newKey = key . replace ( / _ / i , '' ) item [ newKey ] = item [ key ] delete item [ key ] transformKeys ( a )

方法二:深度优先遍历(非递归)

function dfs(obj) {
    const list = []
    if (!obj) return list
    const stack = []
    stack.push(obj)
    while (stack.length) {
        let item = stack.pop()
        for (let key in item) {
            if (typeof item[key] === 'object' && item[key] !== null) {
                list.push(item[key])
                stack.push(item[key])
    return list
function transformKeys(obj) {
    const list = dfs(obj)
    list.forEach(item => {
        for (let key in item) {
            const newKey = key.replace(/_/i, '')
            item[newKey] = item[key]
            delete item[key]
transformKeys(a)

方法三:深度优先遍历的另一种形式(递归)

function transformKeys(obj) {
    let keys = Object.keys(obj)
    keys.forEach(key => {
        if (typeof obj[key] === 'object' && obj[key] !== null) {
            transformKeys(obj[key])
        const newKey = key.replace(/_/i, '')
        obj[newKey] = obj[key]
        delete obj[key]

方法四:广度优先遍历(非递归)

function bfs(obj) {
    const list = []
    if (!obj) return list
    const stack = []
    stack.push(obj)
    while (stack.length) {
        let item = stack.shift() // 和深度优先遍历的唯一差别
        for (let key in item) {
            if (typeof item[key] === 'object' && item[key] !== null) {
                list.push(item[key])
                stack.push(item[key])
    return list
function transformKeys(obj) {
    const list = bfs(obj)
    list.forEach(item => {
        for (let key in item) {
            const newKey = key.replace(/_/i, '')
            item[newKey] = item[key]
            delete item[key]
transformKeys(a)
let arr = [obj]; while ((ele = arr.pop())) { for (const key in ele) { if (Object.hasOwnProperty.call(ele, key)) { let o = ele[key]; delete ele[key]; let k = key.replace(/_?/g, ""); ele[k] = o; typeof o === "object" && arr.push(o); return obj;
function fn(obj) {
  try {
    return JSON.parse(JSON.stringify(obj).replace(/(\"\w)_(\w\"\:)/g, '$1$2'))
  } catch (error) {
    console.error(error)
  while(stack.length) {
    let current = stack.shift()
    let child = current.parent[current.key]
    // 有下一层放进数组
    if(typeof child === 'object') {
      stack = stack.concat(getKeyList(child))
    // 处理当前节点替换
    let newKey = current.key.replace('_', '')
    current.parent[newKey] = child
    delete current.parent[current.key]
  return obj
const getKeyList = (obj) => {
  return Object.keys(obj).map(val => {
    return {
      key: val,
      parent: obj
console.log(replaceName(a))
while (q.length) { let curr = q.shift() let keys = Object.keys(curr.value) let newKey = curr.key.replace(/_(\w)/g, function(_, $1) { return $1.toUpperCase() curr.parent[newKey] = curr.value delete curr.parent[curr.key] if (keys.length) { q.push(...keys.map(key => ({ key, value: curr.value[key], parent: curr.parent[newKey] }))) return data
function changeKey(data){
   return  JSON.parse(JSON.stringify(data).replace(/_/g,''));
const a = {
    a_y: {
      a_z: {
        y_x: 6
      b_c: 1
changeKey(a)
while(arr.length) { const current = arr.shift(); for (let key of Object.keys(current)) { const changedKey = key.replace('_', '') current[changedKey] = current[key] delete current[key] arr.push(current[changedKey]) console.log('result: ', root) bfs(obj)
function bgfObj ( obj , fn ) { let toString = Object . prototype . toString let queue = [ obj ] while ( queue . length !== 0 ) { let temp = queue . shift ( ) if ( 'Object]' === toString . call ( temp ) . substring ( 8 ) ) { queue . push ( ... Object . values ( temp ) ) fn ( temp ) bgfObj ( a , obj => { Object . keys ( obj ) . forEach ( key => { if ( / _ / . test ( key ) ) { obj [ key . replace ( '_' , '' ) ] = obj [ key ] // 不考虑有多个 _ delete obj [ key ] console . log ( 'bgfObj, a: ' , JSON . stringify ( a ) ) ; let item = stack . pop ( ) ; for ( let i in item ) { if ( typeof item [ i ] == "object" && item [ i ] != null ) { stack . push ( item [ i ] ) ; let newKey = i . replace ( / _ / i , "" ) ; item [ newKey ] = item [ i ] ; delete item [ i ] ; return list ; console . log ( formatKey ( a ) ) ; for (let key in current) { if (current.hasOwnProperty(key)) { const currentKey = key.replace('_', '') current[currentKey] = current[key] delete current[key] arr.push(current[currentKey]) return obj console.log(fn(a)) while ( stack . length ) { const cur = stack . pop ( ) ; for ( let key in cur ) { const newKey = key . replace ( "_" , "" ) ; cur [ newKey ] = cur [ key ] ; delete cur [ key ] ; if ( typeof cur [ newKey ] === "object" ) { stack . push ( cur [ newKey ] ) ; var data = cur . data ; // 本次遍历的对象所属Key值,重新建立一个新的key来存放遍历对象的结果 var curKey = cur . key ; // 存储之前转换的结果 var curRoot = cur . root ; // 存储本次转换的结果 var res = curRoot ; // 为对应的Key值建立空对象Value if ( curKey ) { res = curRoot [ curKey ] = { } ; for ( var key in data ) { var newKey = key . replace ( / _ / g , "" ) ; if ( Object . prototype . toString . call ( data [ key ] ) === "[object Object]" ) { arr . push ( { root : res , data : data [ key ] , key : newKey , } ) ; } else { res [ newKey ] = data [ key ] ; console . log ( newObj ) return newObj cloneAndFormat ( a ) // 输出 => 符合预期 // { ay: { bc: 1, az: { yx: 6, zd: 2 } } } // 递归方法 function deepClone ( obj ) { var target = { } ; for ( var key in obj ) { var newKey = key . replace ( / _ / g , "" ) ; if ( Object . prototype . toString . call ( obj [ key ] ) === "[object Object]" ) { target [ newKey ] = deepClone ( obj [ key ] ) ; } else { target [ newKey ] = obj [ key ] ; return target ; deepClone ( a ) // 输出 => 符合预期 // { ay: { bc: 1, az: { yx: 6, zd: 2 } } } for (let key in item) { console.log("key: ", key); if (typeof item[key] === "object" && item[key] !== null) { formatKeyDFS(item[key]); let newKey = key.replace(/_/, ""); item[newKey] = item[key]; delete item[key]; return item; // dfs 非递归 function formatKeyDFS2(obj) { let stack = [obj]; while (stack.length) { let item = stack.pop(); // 倒序遍历子节点 let keys = Object.keys(item).reverse(); for (let key of keys) { if (typeof item[key] === "object" && item[key] !== null) { stack.push(item[key]); let newKey = key.replace(/_/, ""); item[newKey] = item[key]; delete item[key]; return obj; // bfs function formatKeyBFS(obj) { let queue = [obj]; while (queue.length) { let item = queue.shift(); for (let key in item) { console.log("key: ", key); if (typeof item[key] === "object" && item[key] !== null) { queue.push(item[key]); let newKey = key.replace(/_/, ""); item[newKey] = item[key]; delete item[key]; return obj; console.log(formatKeyDFS2(a));
{ ay: { bc: 1, az: { yx: 6 } } }
    while(sk.length){
        let last = sk.pop()//弹出栈顶一项
        Object.keys(last).forEach(el=>{
            let key = el.replace('_','')
            last[key] = last[el]
            delete last[el]
            sk1.push(last)
            if(typeof last[key] == 'object' ){
                sk.push(last[key])
    return sk1[0]
console.log(chanKey(a));
for(const i of q) {
if(typeof i === 'object' && Object.keys(i).length > 0) {
for(const key of Object.keys(i)){
const newKey = key.replace('_', '')
i[newKey] = i[key]
q.push(i[newKey])
if (newKey !== key) {
delete i[key]
return raw
formatObject(o)

var obj = {};
for(var i in pObj) {
if(pObj.hasOwnProperty(i) && typeof pObj[i] === 'object') {
obj[ ${transfer(i)} ] = run(pObj[i])
} else if(pObj.hasOwnProperty(i)) {
obj[ ${transfer(i)} ] = pObj[i]
return obj
while ( stack . length ) { let curObj = stack . pop ( ) ; let keys = Object . keys ( curObj ) ; keys . forEach ( ( key ) => { let newKey = key . replace ( "_" , "" ) ; curObj [ newKey ] = curObj [ key ] ; delete curObj [ key ] ; if ( typeof curObj [ newKey ] === "object" ) { stack . push ( curObj [ newKey ] ) ; } ) ; replaceName ( a ) ; function remove_ ( obj ) { const string = JSON . stringify ( obj ) . replace ( / _ / g , "" ) const json = JSON . parse ( string ) console . log ( json ) ; return string ; remove_ ( a ) while ( queue . length ) { const _current = queue . shift ( ) ! ; Object . keys ( _current ) . forEach ( ( key ) => { const _newKey = key . replace ( / _ / g , '' ) ; _current [ _newKey ] = _current [ key ] ; delete _current [ key ] ; if ( typeof _current [ _newKey ] === 'object' ) { queue . push ( _current [ _newKey ] ) ; return obj ; const reg = / \_ / ; while ( list . length > 0 ) { const current = list . pop ( ) ; // 随意拿到一个当前的值 for ( let key of Object . keys ( current ) ) { const afterKey = key . replace ( reg , '' ) ; current [ afterKey ] = current [ key ] ; delete current [ key ] // 判断是否为对象 if ( Object . prototype . toString . call ( current [ afterKey ] ) === '[object Object]' ) { list . push ( current [ afterKey ] ) ; // 利用数组的特性递归 实际上也是递归的一种 console . log ( target ) ; return target console . time ( ) bfs ( a ) console . timeEnd ( ) function updateKey ( obj ) { return JSON . parse ( JSON . stringify ( obj ) . replace ( / (\w)_(\w) / g , '$1$2' ) ) console . log ( updateKey ( a ) )
function flatSingle(obj) {
  return Object.keys(obj).map(k => ({ parent: obj, key: k, value: obj[k] }))
function flatFunc(obj) {
    let queue = flatSingle(obj, obj)
    while (queue.length) {
      const left = queue.shift();
      const key = left.key.replace(/_/g, '');
      if (Object.prototype.toString.call(left.value) === '[object Object]') {
        queue = queue.concat(flatSingle(left.value))
      left.parent[key] = left.value;
      if (left.key.includes('_')) {
        delete left.parent[left.key];
    return obj;
function modifyKey(input) {
  const obj = JSON.stringify(input).replace(/_/g, '')
  return JSON.parse(obj)
console.log(modifyKey(a))
          
const transfer = function (obj) {
  const arr = [obj];
  while (arr.length) {
    const item = arr.shift();
    for (let i in item) {
      if (Object.prototype.toString.call(item[i]) === "[object Object]") {
        arr.push(item[i]);
      item[i.replace(/_/, "")] = item[i];
      delete item[i];
  return obj;
    let cur = stack.pop()
    for (let key in cur) {
      let newKey = key.replace('_', '')
      cur[newKey] = cur[key]
      delete cur[key]
      if (cur[newKey] instanceof Object) {
        stack.push(cur[newKey])
const target = arr.pop();
change(target); // 对对象里的数据进行名称转化
if (target instanceof Object) { // 如果是对象的话,继续将他的属性加进去
for (let i in target) {
arr.push(target[i]);
console.log(data);
return data;
const change = (data) => {
const key = Object.keys(data);
const reg = /_/g;
for (let i = 0; i < key.length; i++) {
let tempKey = key[i].replace(reg, '');
data[tempKey] = data[key[i]];
delete data[key[i]];
const a = {
a_y: {
a_z: {
y_x: 6,
z_j: 7,
b_c: 1
adc(a)

function changeObjectProperty(obj) { let reg = new RegExp(/("\w+)_(\w+":)/g); return JSON.parse(JSON.stringify(obj).replace(reg, '$1$2')) console.log(changeObjectProperty(a));

item[name] = item[i]
delete item[i]
if (typeof item[name] === 'object' && item[name] !== null) {
stack.push(item[name])
stack.shift()
return obj
function updateKey(obj) {
  if (Object.prototype.toString.call(obj) === '[object Object]') {
     return JSON.parse(JSON.stringify(obj).replace(/_/g, ''));
  return obj;
function updateObj(obj) {
if (obj !== null && typeof obj === 'object') {
Object.keys(obj).forEach((key) => {
const key1 = key.replace(/_/g, '')
obj[key1] = obj[key]
delete obj[key]
return updateObj(obj[key1])
return obj
let changeObjName = function(obj) { let stack = [obj]; while(stack.length) { let top = stack.pop(); for(let key in top) { if(Object.prototype.toString.call(top) === '[object Object]') { stack.push(top[key]) top[key.split('_').join('')] = top[key]; delete top[key]; return obj; //递归实现 let changeObjName = function(obj) { return Object.keys(obj).reduce((newObj, key)=> { let newKey = key.split('_').join(''); newObj[newKey] = (obj && typeof obj[key] === 'object') ? changeObjName(obj[key]): obj[key]; return newObj; }, {}) while (stack.length) { const item = stack.pop() for (const key in item) { if (typeof item[key] === 'object') { stack.push(item[key]) list.push(item[key]) return list function transferKey(obj) { const list = dfs(obj) list.forEach(item => { for (const key in item) { const newKey = key.replace(/_/g, '') item[newKey] = item[key] delete item[key] transferKey(a) console.log(a)
try { const reg = /(\w+)_(\w+)":/g return JSON.parse(JSON.stringify(obj).replace(reg, (match) => match.replace('_', ''))) } catch (error) { return obj //这周六会重新再写一遍, 目前对 深度优先遍历和广度优先变量不熟
const transformObj= (obj) => {
let res = Object.keys(obj)  ;
  while (res.length) {
    let cur = res.pop()
    for (let key in cur) {
      let newKey = key.replace('_', '')
      cur[newKey] = cur[key]
      delete cur[key]
      if (cur[newKey] instanceof Object) {
        res.push(cur[newKey])
    let res = queue.pop();
    for(let key in res) {
      if(typeof res[key] === 'object' && res[key] !== null) {
        queue.push(res[key]);
      let newKey = key.replace(/_/, '');
      res[newKey] = res[key];
      delete res[key]
  return obj
学习了大佬的bfs
stack . push ( { obj } ) ; while ( stack . length !== 0 ) { let cur = stack . pop ( ) ; Object . keys ( cur ) . forEach ( ( key ) => { if ( typeof cur [ key ] === "object" && ! Array . isArray ( cur [ key ] ) ) { resList . push ( cur [ key ] ) ; stack . push ( cur [ key ] ) ; } ) ; resList . forEach ( ( item ) => { Object . keys ( item ) . forEach ( ( key ) => { let newKey = key . replace ( / _ / g , "" ) ; item [ newKey ] = item [ key ] ; delete item [ key ] ; } ) ; } ) ;
function modifyKey(obj){
    for(const key in obj){
        let k1 = key.replaceAll("_","");
        if(!(obj[key] instanceof Object)){
            obj[k1] = obj[key]
        }else{
            obj[k1] = modifyKey(obj[key]);
        delete obj[key]
    return obj;
            for(const key in obj){
                let k1 = key.replaceAll("_","");
                d[k1] = modifyKey(obj[key]);
            return d;
          
const changeKey = (obj, newObj) => { 
    const keys=Object.keys(obj);
    for(let i = 0; i < keys.length; i++) {
        const key = keys[i];
        newObj[key.replace('_', '')] = obj[key];
        if(typeof obj[key] === 'object') {
            newObj[key.replace('_', '')] ={};
            changeKey(obj[key], newObj[key.replace('_', '')]);
    return newObj;
const a = {
    a_y: {
      a_z: {
        y_x: 6
      b_c: 1
changeKey(a, {})
function handler(obj) {
  function isObject(target) {
    if (Array.isArray(target)) return false;
    return target !== null && typeof target === "object";
  function dfs(obj) {
    if (!isObject(obj)) return;
    Object.keys(obj).forEach((key) => {
      const newKey = key.replaceAll("_", "");
      obj[newKey] = obj[key];
      delete obj[key];
      dfs(obj[newKey]);
  dfs(obj);
  return obj;
          
function transformKey(object) {
  const array = [object]
  while (array.length) {
    const obj = array.pop()
    for (let key in obj) {
      if (Object.prototype.toString.call(obj[key]) === "[object, Object]") {
        array.push(obj[key])
      obj[key.replace(/_/, "")] = obj[key]
      delete obj[key]
  return object
function resolve (obj) {
  let objStr = JSON.stringify(obj)
  let arr = objStr.match(/"\w_\w":/g).map(item => item.replace(/_/g,''))
  for(let i of arr){
    objStr = objStr.replace(/"\w_\w":/, i)
  return JSON.parse(objStr)
console.log(resolve(a))
const keyTransformer = (obj, fn) =>
    Object.keys(obj).reduce((acc, current) => {
        const key = fn(current);
        const val = obj[current];
        acc[key] =
          val !== null && typeof val === 'object' ? keyTransformer(val, fn) : val;
        return acc;
      }, {});
const a = {
  a_y: {
    a_z: {
      y_x: 6
    b_c: 'asdas_c'
const underscoreKeysObj = keyTransformer(a, key => key.split('_').join(''));
            // 如果是对象,推入队列继续
            if (typeof item[newKey] === 'object' && item[newKey] !== null) {
                queue.unshift(item[newKey]);
    return a;
const a = removeUnderScore({
    a_y: {
      a_z: {
        y_x: 6
      b_c: 1
console.log(a);
          
function transfer(obj) {
  return JSON.parse(JSON.stringify(obj).replace(/"(\w)_(\w):"/g, '$1$2:'));
          

想了好长时间用了一个笨办法

const editDeepKey = (obj = {}) => {
    const result = {}; // 处理的结果
    const shed = []; // 栈信息
    let index = 0; // 当前栈索引
    // 推进第一级入栈
    Object.keys(obj).length && shed.push({
        obj: obj,
        keys: Object.keys(obj), // 第一级所有的key
        convert_key: '', // 转化之后的key
        index: 0, // 遍历索引
    });
    while (shed.length) {
        const current = shed[index];  // 当前内容栈
        let receive_data = result; // 接收对象
        const key = current.keys[current.index]; // 当前遍历原数据的key
        let convert_key = ''; // 转化之后的key值
        // 如果key不存在说明是上次上级遇到对象进行子级处理,回到上级之后之前是对象的key处于最后一个位置,后面无需在进行处理
        // 直接将该栈数据删除出栈即可
        if (!key) {
            shed.splice(index, 1); // 清空当前栈内存
            index--; // 减少栈索引
            // 继续下一轮循环
            continue;
        convert_key = key.replace(/([a-zA-Z])_([a-zA-Z])/g, '$1$2'); // 当前遍历目标数据的key
        shed[index].convert_key = convert_key; // 赋值当前遍历目标数据的key
        // for循环确定最终的接收对象
        for (let i = 0; i < index; i++) {
            // 这里不用担心receive_data[shed[i].convert_key]不存在
            // 因为在上次检测到父级key对应的值是一个对象的时候就创建对应的对象
            // 直接等于该对象
            receive_data = receive_data[shed[i].convert_key];
        if (Object.prototype.toString.call(current.obj[key]) === '[object Object]') {
            // 将当前键的值赋值为一个空对象 这里创建相关对象,涉及到上面for循环里面的直接赋值
            receive_data[convert_key] = {}; // 先创建对应键为对象
            // 压栈
            shed.push({
                obj: current.obj[key],
                keys: Object.keys(current.obj[key]), // 当前级所有的key
                convert_key: '', // 转化之后的key
                index: 0, // 遍历索引
            });
            // 增加栈索引
            index++;
            // 索引加1
            current.index++;
            // 继续下一轮循环
            continue;
        // 非对象值
        // 索引加1
        current.index++;
        receive_data[convert_key] = current.obj[key]; // 赋值
        // 本次栈内容全部处理完成 出栈
        if (current.index === current.keys.length) {
            shed.splice(index, 1); // 清空当前栈内存
            index--; // 减少栈索引
    return result;
const a = {
    a_y: {
        a_z: {
            y_x: 6
        b_c: 1
console.time('time');
console.log(editDeepKey(a));
console.timeEnd('time');