Daily-Interview-Question icon indicating copy to clipboard operation
Daily-Interview-Question copied to clipboard

第 111 题:编程题,写个程序把 entry 转换成如下对象

Open yygmind opened this issue 4 years ago • 99 comments

var entry = {
a: {
 b: {
   c: {
     dd: 'abcdd'
   }
 },
 d: {
   xx: 'adxx'
 },
 e: 'ae'
}
}

// 要求转换成如下对象
var output = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}

yygmind avatar Jul 23 '19 01:07 yygmind

我先来

function flatObj(obj, parentKey = "", result = {}) {
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      let keyName = `${parentKey}${key}`;
      if (typeof obj[key] === 'object')
        flatObj(obj[key], keyName+".", result)
      else
        result[keyName] = obj[key];
    }
  }
  return result;
}

MoveZZG avatar Jul 23 '19 01:07 MoveZZG

function isObject (obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
}
function flatObj (obj, prefix = '', res = {}) {
    for (let i in obj) {
        let key = prefix ? prefix + '.' + i : i
        isObject(obj[i]) ? flatObj(obj[i], key, res) : (res[key] = obj[i])
    }
    return res
}

simbaHuang avatar Jul 23 '19 01:07 simbaHuang

var entry = {
  a: {
    b: {
      c: {
        dd: 'abcdd'
      }
    },
    d: {
      xx: 'adxx'
    },
    e: 'ae'
  }
}

var keys = [];
function flatObj(from, to) {
  for (var key in from) {
    var res = from[key];
    keys.push(key);
    if (typeof res === "object") {
      flatObj(res, to);
    } else {
      to[keys.join(".")] = res;
    }
    keys.pop();
  }
}

var output = {};
flatObj(entry, output);
console.log(output);

clwu1994 avatar Jul 23 '19 01:07 clwu1994

function en(obj) {
    const keyArr = [];
    const newObj = {};
    const _c = function (o) {
        for (k in o) {
            keyArr.push(k);
            if (typeof o[k] === 'object') {
                _c(o[k]);
            } else {
                newObj[keyArr.join('.')] = o[k];
                keyArr.pop();
            }
        }
        keyArr.pop();
    }
    _c(obj);
    return newObj;
}

hpysirius avatar Jul 23 '19 01:07 hpysirius

bfs

function flatObj(entry) {
	const queue = Object.entries(entry)
	const res = {}
	while (queue.length) {
		const [key, obj] = queue.pop()
		for (const [k, v] of Object.entries(obj)) {
			if (typeof v !== 'object') {
				res[`${key}.${k}`] = v
			} else {
				queue.push([`${key}.${k}`, v])
			}
		}
	}
	return res
}

ZodiacSyndicate avatar Jul 23 '19 02:07 ZodiacSyndicate

function func (origin, output = {}, keys = []) => {
  if (typeof origin === 'object') {
    for (const k in origin) {
      generate(origin[k], output, [...keys, k])
    }
  } else {
    output[keys.join('.')] = origin
  }
}
const output = {}
func(entry, output)
console.log('output', output)

j-colter avatar Jul 23 '19 02:07 j-colter

    var obj = {
        a: {
            b: {
                c: {
                    dd: 'abcdd'
                }
            },
            d: {
                xx: 'adxx'
            },
            e: 'ae'
        }
    };

    function convert(target,preKey = '',result = {}){
        let keys = Object.keys(target),
            len = keys.length;

        while(len--){
            let curKey = keys[len];
            let targetKey = preKey ? `${preKey}.${curKey}` : curKey;
            if(Object.prototype.toString.call(target[curKey]) === '[object Object]'){
                convert(target[curKey],targetKey,result);
            }else{
                result[targetKey] = target[curKey];
            }
        }

        return result;
    }

    console.log(convert(obj));

linlinyang avatar Jul 23 '19 02:07 linlinyang

    function flat(obj, key = "", res = {}) {
      Object.keys(obj).forEach(k => {
        if (Object.prototype.toString.call(obj[k]) == "[object Object]") {
          flat(obj[k], key + k + ".", res);
        } else {
          res[key + k] = obj[k];
        }
      });
      return res;
    }
    console.log(flat(entry));

harryliuy avatar Jul 23 '19 02:07 harryliuy

题目

var entry = {
    a: {
        b: {
            c: {
                dd: 'abcdd'
            }
        },
        d: {
            xx: 'adxx'
        },
        e: 'ae'
    }
};

// 要求转换成如下对象
var output = {
    'a.b.c.dd': 'abcdd',
    'a.d.xx': 'adxx',
    'a.e': 'ae'
};

实现方案

思路 遍历对象,遇到还是对象的地方递归深入即可。

核心代码:

/**
 *
 * @param {String | null} prevKey 前面的key
 * @param {Object} obj 当前操作对象
 * @returns {Array<Object>} 扁平化后的对象数组
 */
function getFlat(prevKey, obj) {
    const arr = [];
    Object.keys(obj).forEach(k => {
        const currentKey = prevKey ? `${prevKey}.${k}` : k;
        if (Object.prototype.toString.call(obj[k]) != '[object Object]') {
            arr.push({
                [currentKey]: obj[k]
            });
        } else {
            arr.push(...getFlat(currentKey, obj[k]));
        }
    });

    return arr;
}

以给定代码为例,即可转化为如下形式,然后进行合并即可。

[
    {'a.b.c.dd': 'abcdd'},
    {'a.d.xx': 'adxx'},
    {'a.e': 'ae'},
]

如果不考虑纯函数的问题,可以初始就定义一个空对象,然后在递归函数中直接将每次的结果写入,这样就少了后续的合并操作,详见后续实现中的 flatObject2

完整代码

var entry = {
    a: {
        b: {
            c: {
                dd: 'abcdd'
            }
        },
        d: {
            xx: 'adxx'
        },
        e: 'ae'
    }
};
/**
 * 对象扁平化
 * @param {Object}  obj 操作对象
 * @returns {Object} 扁平化后的对象
 */
function flatObject(obj) {
    const flat = {};

    return Object.assign(flat, ...getFlat(null, obj));

    /**
     *
     * @param {String | null} prevKey 前面的key
     * @param {Object} obj 当前操作对象
     * @returns {Array<Object>} 扁平化后的对象数组
     */
    function getFlat(prevKey, obj) {
        const arr = [];
        Object.keys(obj).forEach(k => {
            const currentKey = prevKey ? `${prevKey}.${k}` : k;
            if (Object.prototype.toString.call(obj[k]) != '[object Object]') {
                arr.push({
                    [currentKey]: obj[k]
                });
            } else {
                arr.push(...getFlat(currentKey, obj[k]));
            }
        });

        return arr;
    }
}

console.log(JSON.stringify(flatObject(entry), 0, 4));
// {
//     "a.b.c.dd": "abcdd",
//     "a.d.xx": "adxx",
//     "a.e": "ae"
// }

/**
 * 对象扁平化
 * @param {Object}  obj 操作对象
 * @returns {Object} 扁平化后的对象
 */
function flatObject2(obj) {
    const flat = {};
    getFlat(null, obj);
    return flat;
    /**
     * 递归将对象扁平化
     * @param {String | null} prevKey 前面的key
     * @param {Object} obj 当前操作对象
     */
    function getFlat(prevKey, obj) {
        Object.keys(obj).forEach(k => {
            const currentKey = prevKey ? `${prevKey}.${k}` : k;
            if (Object.prototype.toString.call(obj[k]) != '[object Object]') {
                flat[currentKey] = obj[k];
            } else {
                getFlat(currentKey, obj[k]);
            }
        });
    }
}
console.log(JSON.stringify(flatObject2(entry), 0, 4));
// {
//     "a.b.c.dd": "abcdd",
//     "a.d.xx": "adxx",
//     "a.e": "ae"
// }

magicds avatar Jul 23 '19 02:07 magicds

function flatObj(entry){
  function rec (entry, parentKey , result){
    Object.keys(entry).forEach((key) => {
       if(typeof entry[key] === 'object') {
         rec(entry[key], parentKey + key, result)
    } else {
         const keyname = parentKey.replace(/(?=\B)/g, '.')+ '.' +key
      result[keyname] = entry[key]
    }
    })
  }
  rec(entry, parentKey = '', result = {}) 
  return result
}

Dark-volute avatar Jul 23 '19 02:07 Dark-volute

function flatObj(obj) { let arr = Object.entries(obj); arr.map(item => { if(typeof item[1] === 'object'){ let keys = Object.keys(item[1]); let values = Object.values(item[1]); let temp = {}; for(let i=0;i<keys.length;i++) { temp[${item[0]}.${keys[i]}] = values[i] } flatObj(temp) }else { output[item[0]] = item[1]; } }) }

entenity avatar Jul 23 '19 02:07 entenity

        function objs(_old,key,_new){
            if(!key) key = '';
            if(!_new)_new = {};
            for(let attr in _old){
                let data = _old[attr];
                if(data!=null && typeof data === 'object'){
                     objs(data,key+attr+'.',_new);
                }else{
                    _new[key+attr] = data;
                }
            }
            return _new;
        }

        console.log(objs({
            a:{
                b:{
                    c:{
                      dd:'abcdd'
                    }
                },
                d:{
                    xx:{
                        cc:'xxxx'
                    }
                },
                e:'ae',
                g:{
                  ooxx:'xxx'  
                }
            }
        }));

xiaohei007 avatar Jul 23 '19 02:07 xiaohei007

function flatJson(obj = {}, parentKey = '', res = {}) {
    for (let k in obj) {
        if (typeof obj[k] !== 'object' && obj[k] !== null) {
            res[`${parentKey}${k}`] = obj[k];
        } else {
            flatJson(obj[k], `${parentKey}${k}.`, res);
        }
    }
    return res;
}

大相径庭

win7killer avatar Jul 23 '19 02:07 win7killer

var entry = {
    a: {
        b: {
            c: {
                dd: 'abcdd'
           }
        },
        d: {
            xx: 'adxx'
        },
        e: 'ae'
    }
}
/**
 * [getFlat]
 * @param  {[Object]} entry [传入对象]
 * @param  {String} hea   [属性名前缀]
 * @param  {Object} res   [返回对象]
 */
function getFlat (entry, hea = '', res = {}) {
    for (let k in entry) {
        if (entry.hasOwnProperty(k)) {
            if (Object.prototype.toString.call(entry[k]) === '[object Object]' ) {
                getFlat(entry[k], hea + k + '.', res)
            } else {
                res[hea + k] = entry[k]
            }
        }
    }
    return res
}
console.log(getFlat(entry))
// 1.先遍历,判断是否包含属性
// 2.属性值是对象继续递归
// 3.属性值不是对象返回

ZTrainWilliams avatar Jul 23 '19 02:07 ZTrainWilliams

const flattenObject = (obj, prefix = '') =>
  Object.keys(obj).reduce((acc, k) => {
    const pre = prefix.length ? prefix + '.' : '';
    if (typeof obj[k] === 'object') Object.assign(acc, flattenObject(obj[k], pre + k));
    else acc[pre + k] = obj[k];
    return acc;
  }, {})

svenjia avatar Jul 23 '19 02:07 svenjia

function chang(obj, parentKey = '', res = {}) {
	for(let i in obj) {
		let Key = parentKey ? (parentKey + '.' + i) : i;
		(typeof obj[i] === 'object')?chang(obj[i], Key, res):res[Key] = obj[i];
	}
	return res
}

console.log(chang(entry))//{a.b.c.dd: "abcdd", a.d.xx: "adxx", a.e: "ae"}

EnergySUD avatar Jul 23 '19 02:07 EnergySUD

function fun111(entry) { let array111 = {} function fun111_1 (entry, f) { for (let i in entry) { let t = f ? ${f}.${i} : i if (typeof entry[i] === 'string') { array111[t] = entry[i] } else { fun111_1(entry[i], t) } } } fun111_1(entry) return array111 }

hlubing avatar Jul 23 '19 02:07 hlubing

`var entry = { a: { b: { c: { dd: 'abcdd' } }, d: { xx: 'adxx' }, e: 'ae' } }

	function getOutput(obj){
		let parentKey = '';
		let output = {};
		
		if(Object.prototype.toString.call(entry) === '[object Object]'){
			(function getKeys(obj, str){
				for(let key in obj){
					let newStr = str === '' ? key : `${str}.${key}`;
					
					if(Object.prototype.toString.call(obj[key]) === '[object Object]'){
						getKeys(obj[key], newStr);
					}else{
						output[newStr] = obj[key];
					}
				}		
			})(obj, '')
		}else{
			console.log('传入的不是对象');
		}
		
		return output;
	}
	
	getOutput(entry)`

skyunBoss avatar Jul 23 '19 02:07 skyunBoss

var entry = {
    a: {
      b: {
        c: {
          dd: 'abcdd'
        }
      },
      d: {
        xx: 'adxx'
      },
      e: 'ae'
    }
  }

  const deepFlat = (obj) => {
    let res = {}
    function deep(obj, prekey = '') {
      for (let key of Object.keys(obj)) {
        if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
          deep(obj[key], prekey ? `${prekey}.${key}` : key)
        } else {
          res[`${prekey}.${key}`] = obj[key]
        }
      }
    }
    deep(obj)
    return res
  }

  console.log(deepFlat(entry))

k-0311 avatar Jul 23 '19 02:07 k-0311

function fun1(obj, str = '', result = {}) {

  Object.keys(obj).forEach((key) => {

    if (typeof obj[key] == 'object') {
      fun1(obj[key], str + key + '.', result)
    } else {
      str += key
      result[str] = obj[key]
    }
  })
  return result
}

console.log(fun1(entry))

ch8839 avatar Jul 23 '19 03:07 ch8839

上一版typescript实现

function transformObject(input: any, keyStr: string='', result: any={}): any{
    const keys: Array<string> = Object.keys(input);
    keys.map(key => {
        if (typeof input[key] === 'object') {
            transformObject(input[key], keyStr+`${key}.`, result)
        } else {
            keyStr += `${key}`;
            result[keyStr] = input[key];
        }
    })

    return result
}

sunVictory avatar Jul 23 '19 03:07 sunVictory

const  isObject = (value) => (typeof value === 'object') && (value !== null)

function reduceObject(obj, parentName, resultObj) { // 对 {} 的每个值进行判断
  const keyNames = Object.keys(obj); // ['b', 'd']
  keyNames.forEach(keyName => {
    let currentValue = obj[keyName] // 当前值
    let currentKeyName = parentName ? `${parentName}.${keyName}` : keyName // 当前键名
    // 键值为对象则继续递归, 为其它值则将新的键值对添加到result中
    if(isObject(currentValue)) {
      reduceObject(currentValue, currentKeyName, resultObj)
    } else {
      resultObj[currentKeyName] = currentValue
    }
  })
}

function flatKeyName(obj) {
  let outputObj = {}
  reduceObject(entry, null, outputObj)
  return outputObj
}

console.log(flatKeyName(entry))

YYJay avatar Jul 23 '19 03:07 YYJay

function isPlainObject(obj){
   return Object.prototype.toString.call(obj) === '[object Object]'
}
const output = {}
function parserObj(obj,parentKey=''){
  if(isPlainObject(obj)){
     Object.keys(obj).forEach(key=>{
         parserObj(obj[key],`${parentKey}${key}.`)
     })
  }else{
     output[parentKey] = obj
  }
}
var entry = {
a: {
 b: {
   c: {
     dd: 'abcdd'
   }
 },
 d: {
   xx: 'adxx'
 },
 e: 'ae'
}
}
parserObj(entry)
console.log(output)

pfzhengd avatar Jul 23 '19 03:07 pfzhengd

function flatObj(preKey, obj, result = {}) {
    if (JSON.stringify(obj) === '{}') {
        return {};
    }
    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            const curKey = preKey ? `${preKey}.${key}` : key;
            if (typeof obj[key] !== 'object') {
                result[curKey] = obj[key];
            } else {
                flatObj(curKey, obj[key], result);
            }
        }
    }
    return result;
}

wmc425454438 avatar Jul 23 '19 03:07 wmc425454438

function flatObj(entry, prev = "", result = {}) {
  Object.keys(entry).map((key) =>
    typeof entry[key] === "object"
      ? flatObj(entry[key], prev ? key : `${prev}.${key}`, result)
      : (result[prev ? key : `${prev}.${key}`] = entry[key])
  );
  return result;
}

rquanx avatar Jul 23 '19 04:07 rquanx

        a: {
          b: {
            c: {
              dd: 'abcdd'
            }
          },
          d: {
            xx: 'adxx'
          },
          e: 'ae'
        }
      }

      function exchange(obj) {
        if (typeof obj != 'object') {
          throw new Error('请输入 [object Object] 类型')
        }
        let O = {}
        let digui = function(obj, str) {
          for (let key in obj) {
            let str_ = str + '.' + key
            if (typeof obj[key] == 'object') {
              digui(obj[key], str_)
            } else {
              O[str_.slice(1)] = obj[key]
            }
          }
        }
        let res = digui(obj, '')
        return O
      }
      let res = exchange(entry)
      console.log(res)   //{a.b.c.dd: "abcdd", a.d.xx: "adxx", a.e: "ae"}

weiweixuan avatar Jul 23 '19 04:07 weiweixuan

var entry = {
  a: {
    b: {
      c: {
        dd: 'abcdd',
      },
    },
    d: {
      xx: 'adxx',
    },
    e: 'ae',
  },
}

function flatPlainObj(entry) {
  if (Object.prototype.toString.call(entry) !== '[object Object]') {
    throw new Error('entry must be a plain object')
  }

  var output = {}
  var pathArr = []

  function recur(entry) {
    if (Object.prototype.toString.call(entry) === '[object Object]') {
      Object.keys(entry).forEach(key => {
        pathArr.push(key)
        recur(entry[key])
        pathArr.pop()
      })
    } else {
      output[pathArr.join('.')] = entry
    }
  }

  recur(entry)

  return output
}

console.log(flatPlainObj(entry))

willltns avatar Jul 23 '19 05:07 willltns

function flattern(o, path = '', res = {}) {
  Object.keys(o).forEach((key) => {
    if (Object.prototype.toString.call(o[key]) === '[object Object]' || Array.isArray(o[key])) {
      flattern(o[key], `${path}.${key}`, res)
    } else {
      res[`${path}.${key}`.slice(1)] = o[key]
    }
  });
  return res
}

lhyt avatar Jul 23 '19 05:07 lhyt

深度遍历

   function convert(entry) {
      const queue = [];
      const output = {};
      function dft(obj) {
        const keys = Object.keys(obj);
        for (let i of keys) {
          queue.push(i);
          if (typeof obj[i] === 'object') {
            dft(obj[i]);
          } else {
            output[queue.join('.')] = obj[i];
          }
          queue.pop();
        }
      }
      dft(entry);
      return output;
    }

wycyftk avatar Jul 23 '19 06:07 wycyftk

function f1() { var str = '',obj = {}; return function (en) { for(var i in en){ if(Object.prototype.toString.call(en[i])=="[object Object]" ){ str+=i+'.'; arguments.callee(en[i],str); str = str.slice(0,str.length-1-i.length); }else{ str+=i; obj[str] = en[i]; str = str.slice(0,str.length-1-i.length)+'.';

            }

        }
        console.log(obj);
    }
}

var cc =f1()(entry); 不用闭包是不完美的!

630268501 avatar Jul 23 '19 06:07 630268501