Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

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

Open
yygmind opened this issue Jul 23, 2019 · 99 comments
Open

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

yygmind opened this issue Jul 23, 2019 · 99 comments

Comments

@yygmind
Copy link
Contributor

yygmind commented Jul 23, 2019

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'
}
@MoveZZG
Copy link

MoveZZG commented Jul 23, 2019

我先来

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;
}

@simbaHuang
Copy link

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
}

@clwu1994
Copy link
Contributor

clwu1994 commented Jul 23, 2019

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);

@hpysirius
Copy link

hpysirius commented Jul 23, 2019

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;
}

@ZodiacSyndicate
Copy link

ZodiacSyndicate commented Jul 23, 2019

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
}

@j-colter
Copy link

j-colter commented Jul 23, 2019

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)

@linlinyang
Copy link

linlinyang commented Jul 23, 2019

    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));

@harryliuy
Copy link

harryliuy commented Jul 23, 2019

    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));

@magicds
Copy link

magicds commented Jul 23, 2019

题目

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"
// }

@Dark-volute
Copy link

Dark-volute commented Jul 23, 2019

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
}

@entenity
Copy link

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];
}
})
}

@xiaohei007
Copy link

        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'  
                }
            }
        }));

@win7killer
Copy link

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;
}

大相径庭

@ZTrainWilliams
Copy link

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.属性值不是对象返回

@svenjia
Copy link

svenjia commented Jul 23, 2019

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;
  }, {})

@EnergySUD
Copy link

EnergySUD commented Jul 23, 2019

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"}

@hlubing
Copy link

hlubing commented Jul 23, 2019

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
}

@skyunBoss
Copy link

`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)`

@k-0311
Copy link

k-0311 commented Jul 23, 2019

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))

@ch8839
Copy link

ch8839 commented Jul 23, 2019

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))

@sunVictory
Copy link

上一版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
}

@YYJay
Copy link

YYJay commented Jul 23, 2019

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))

@pfzhengd
Copy link

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)

@wmc425454438
Copy link

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;
}

@rquanx
Copy link

rquanx commented Jul 23, 2019

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;
}

@weiweixuan
Copy link

        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"}

@willltns
Copy link

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))

@lhyt
Copy link

lhyt commented Jul 23, 2019

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
}

@wycyftk
Copy link

wycyftk commented Jul 23, 2019

深度遍历

   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;
    }

@630268501
Copy link

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);
不用闭包是不完美的!

@bbrucechen
Copy link

整体思路:递归深入获取属性字符串,闭包保存拼接的字符串,每次递归结束则去除遍历的属性值

function changeObj() {
  let attr = []
  const output = {}
  return function checkAttr(obj) {
    for(let k in obj) {
      if(Object.prototype.toString.call(obj[k]) == '[object Object]') {
        attr.push(k)
        checkAttr(obj[k])
        attr.pop()
      } else {
        attr.push(k)
        const prop = attr.join('.')
        output[prop] = obj[k]
        attr.pop()
      }
    }
    return output
  }
}

console.log(changeObj()({
  a: {
    b: {
      c: {
        dd: 'abcdd'
      },
      f: {
        k:'jskw',
        g:'sdaw1'
      }
    },
    d: {
      xx: 'adxx'
    },
    e: 'ae'
  }
  }))

@leonwens
Copy link

// 递归
function cook(entry, keyStr, res) {
  for (const key in entry) {
    const value = entry[key];
    if (typeof value === 'string') {
      res[keyStr + key] = value;
    } else {
      cook(value, `${keyStr + key}.`, res);
    }
  }
  return res;
}

//bfs
function bfs(entry) {
  const queue = [];
  const res = {};
  if (entry) {
    queue.push({
      keyList: '',
      value: entry
    });
    while (queue.length > 0) {
      const { keyList, value } = queue.shift();
      Object.keys(value).forEach(key => {
        const _key = `${keyList}${keyList && '.'}${key}`;
        const _value = value[key];
        if (typeof _value === 'string') {
          res[_key] = _value;
        } else {
          queue.push({
            keyList: _key,
            value: _value
          });
        }
      });
    }
  }
  return res;
}

// dfs
function dfs(entry) {
	const stack = [];
  const res = {};
  if (entry) {
    stack.push({
      keyList: '',
      value: entry
    });
    while (stack.length > 0) {
      const { keyList, value } = stack.shift();
      const keys = Object.keys(value);
      for(let i=keys.length-1;i>=0;i--){
      	const key = keys[i]
      	const _key = `${keyList}${keyList && '.'}${key}`;
        const _value = value[key];
        if (typeof _value === 'string') {
          res[_key] = _value;
        } else {
          stack.unshift({
            keyList: _key,
            value: _value
          });
        }
      }
    }
  }
  return res;
}

@wangyangzero
Copy link

对象的扁平化,没有说数组和空对象怎么处理,那就按默认处理了

function flatten(input) {
    let result = {};
    let re = function(key,obj){
        if(obj instanceof Object && !(obj instanceof Array)){
            let empty = true;
            for(let index in obj){
                empty = false;
                re(key ? `${key}.${index}` : index,obj[index]);
            }
            if(empty && key){
                result[key] = {};
            }
        }else{
            result[key] = obj;
        }
    };
    re('',input);
    return result;
}

@leonwens
Copy link

function transform(target, keyList=[], result={}) {
      if(typeof target === 'string'){
        result[keyList.join('.')] = target
      }else{
        Object.keys(target).forEach((key)=>{
          transform(target[key], [...keyList, key], result)
        })
      }
      return result
}

@1368725603
Copy link

var entry = {
	a: {
		b: {
			c: {
				dd: 'abcdd'
			}
		},
		d: {
			xx: 'adxx'
		},
		e: 'ae'
	},
	b: 1
}
console.log('trans(entry): ', trans(entry));
function trans(obj) {
	var output = {};
	temp(obj, output, '');
	function temp(obj, output = {}, key = '') {
		for (var [k, v] of Object.entries(obj)) {
			if (typeof v != 'object') {
				output[key + k] = v;
			} else {
				temp(v, output, key + k + '.');
			}
		}
	};
	return output;
}

@yangjiedage
Copy link

遍历树

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

function bar2(obj, parentKey) {
  let nodes = []
  Object.keys(obj).forEach(key => {
    let parentKeyNext = parentKey ? `${parentKey}.${key}` : key
    if(typeof obj[key] === 'object') {
      nodes = nodes.concat(bar2(obj[key], parentKeyNext))
    } else {
      nodes.push({
        parentKey: parentKeyNext,
        val: obj[key]
      })
    }
  })
  return nodes
}

console.log(bar2(entry, ''))
/*
[
  { parentKey: 'a.b.c.dd', val: 'abcdd' },
  { parentKey: 'a.d.xx', val: 'adxx' },
  { parentKey: 'a.e', val: 'ae' },
  { parentKey: 'hh.0.aa', val: 'aa' }
]

*/

@aitexiaoy
Copy link

function flatObj(obj,key='',result={}){
    if(typeof obj !== 'object' || obj===null){
        result[key] = obj
        return
    }

    Object.keys(obj).forEach(k=>{
        flatObj(obj[k], `${key}${key?'.':''}${k}`,result)
    })
    
    return result
}

@LamWaiBen
Copy link

function flagObj(obj, key = '', res = {}) {
    if (typeof obj != 'object' || !obj) {
        res[key] = obj
    } else {
        for (let k in obj) {
            flagObj(obj[k], `${key ? key + '.' : key}${k}`, res)
        }
    }
    return res
}

@jwyw
Copy link

jwyw commented Jun 29, 2020

const isObj = (a) => typeof a === 'object' && a !== null;
const simpleObj = (obj) => {
    const stack = [obj];
    let current;
    const out = {};
    const _p = Symbol('_p');
    const _pNode = Symbol('_pNode');
    while(stack.length) {
        current = stack.pop();
        if (isObj(current)) {
            Object.keys(current).reverse().forEach(key => {
                stack.push(current[key]);
                if (!isObj(current[key])) {
                    let temp = key;
                    let currentTemp = current;
                    while(currentTemp && currentTemp[_p]) {
                        temp = `${currentTemp[_p]}.${temp}`;
                        currentTemp = currentTemp[_pNode];
                    }
                    out[temp] = current[key];
                } else {
                    current[key][_pNode] = current;
                    current[key][_p] = key;
                }
            });
        }
    }
    return out;
}
var entry = {
    a: {
      b: {
        c: {
          dd: 'abcdd'
        }
      },
      d: {
        xx: 'adxx'
      },
      e: 'ae'
    }
  }
console.log(simpleObj(entry));

@eatureide
Copy link

eatureide commented Jul 8, 2020

function transformObj(obj) {

  const newObj = {}
  const objArray = []
  const topKey = Reflect.ownKeys(obj).shift()
  const firstKey = obj[topKey]
  Reflect.ownKeys(firstKey).forEach((key) => objArray.push(JSON.stringify({ [key]: firstKey[key] })))
  const resultArray = objArray.map((item) => item.replace(/{|"|}|/g, ''))

  resultArray.forEach((item) => {
    const key = item.split(':')
    const value = key.pop()
    newObj[topKey + '.' + key.toString().replace(/,/g, '.')] = value
  })

  return newObj
}

transformObj(entry)

思路是解析为字符串再转换

@Tnc-u
Copy link

Tnc-u commented Jul 31, 2020

var entry = {
    a: {
        b: {
            c: {
                dd: 'abcdd'
            }
        },
        d: {
            xx: 'adxx'
        },
        e: 'ae'
    }
}
function change(entry, fkey = '', res = {}){
        if(typeof entry != 'object'){
            res[fkey] = entry
            return
        }
        for(let key in entry){
            if(fkey !== ''){
                change(entry[key], `${fkey}.${key}`, res)
            }else{
                change(entry[key], `${key}`, res)
            }
        }
        return res
    }

console.log(change(entry))

@menggong
Copy link

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
}

bfs的话应该queue.shift(),另外没考虑{a:1}这种情况,按你代码输出是{},简单修改下:

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

@wabRul
Copy link

wabRul commented Sep 3, 2020

function flatObj(obj) {
  let res = {}
  function dfs(str, obj) {
    if (typeof obj !== 'object') {
      res[str] = obj
      return
    }
    for (let i in obj) {
      let s = str === '' ? i : `${str}.${i}`
      dfs(s, obj[i])
    }
  }
  dfs('', obj)
  return res
}

@crabkiller
Copy link

function isObject(obj) {
  return Object.prototype.toString.call(obj) === '[object Object]'
}
function parseToObj(obj, paths = []) {
  if (!isObject(obj)) {
    return paths.length > 0
      ? { [paths.join('.')]: obj }
      : obj
  }
  return Object.keys(obj).reduce((res, key) => {
    Object.assign(res, parseToObj(obj[key], paths.concat(key)))
    return res
  }, {})
}

const testObj = {
  a: {
   b: {
     c: {
       dd: 'abcdd'
     }
   },
   d: {
     xx: 'adxx'
   },
   e: 'ae'
  }
}
console.log(parseToObj(testObj))

@z253573760
Copy link

z253573760 commented Oct 8, 2020

function hadnler(entry, str = "", map = {}) {
  Object.keys(entry).forEach(item => {
    const res = entry[item]
    if (typeof res != "object") {
      map[str + item] = res
    } else {
      hadnler(res, str + item + ".", map)
    }
  })
  return map
}

@huangnuoen
Copy link

      function convert(entry) {
        let obj = {};
        helper(entry, "", obj);
        return obj
      }
      function helper(entry, pKey, obj) {
        for (const key in entry) {
          if (typeof entry[key] == "string") {
            let keyname = `${pKey}${key}`;
            obj[keyname] = entry[key];
          } else {
            helper(entry[key], `${pKey}${key}.`, obj);
          }
        }
      }

@m7yue
Copy link

m7yue commented Oct 15, 2020

  const trans = (entry) => {
    let outPut = {}
    const run = (entry, name = '') => {
      const keys = Object.keys(entry)
      for(let key of keys) {
        let v = entry[key]
        let t = name ? `${name}.${key}` : key
        if(typeof v !== 'object') {
          outPut[t] = v
        }else {
          run(v, t)
        }
      }      
    }
    run(entry)
    return outPut
  }
  trans(entry)

@negativeentropy9
Copy link

function format(entry) {
    const result = {}

    recur(entry)

    return result

    function recur(obj, path = []) {
        Object.keys(obj).forEach((key) => {
            const value = obj[key]

            if (typeof value === 'object') {
                recur(value, [...path, key])
            } else {
                const id = path.length ? `${path.join(".")}.${key}` : key
                
                result[id] = value;
            }
        })
    }
}

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

console.log("debug-", format(entry));

@huxiaocheng
Copy link

function objTransitionStr(entry) {
  const res = {};
  const _helper = (obj, key = "") => {
    if (typeof obj !== "object") {
      res[key.slice(1)] = obj;
      return;
    }
    const keys = Object.keys(obj);
    const values = Object.values(obj);
    for (let i = 0; i < keys.length; i++) {
      _helper(values[i], `${key}.${keys[i]}`);
    }
  };
  _helper(entry);
  return res;
}

@zhelingwang
Copy link

// 递归解法
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'
}

function transform(entry) {
  let output = {};
  function _inner(target, path) {
    if (target === null || typeof target !== 'object') {
      return output[path] = target;
    }
    Reflect.ownKeys(target).forEach(key => {
      _inner(target[key], path ? `${path}.${key}` : `${key}`);
    });
  }
  _inner(entry, '');
  return output;
}

console.log(transform(entry));

@MrLeihe
Copy link

MrLeihe commented May 11, 2021

function flatObj(obj) {
  var res = {}

  function dfs(obj, preKey = '') {
    Reflect.ownKeys(obj).forEach(key => {
      var keyName = `${preKey}${key}`
      if(typeof obj[key] === 'object') {
        dfs(obj[key], keyName + '.')
      } else {
        res[keyName] = obj[key]
      }
    })
  }

  dfs(obj)
  
  return res
}

flatObj(entry)

@Yofun
Copy link

Yofun commented Jul 21, 2021

/**
 * 1. 对象扁平化
 */
function flat(obj, pre = '', result = {}) {
  Object.keys(obj).forEach((v) => {
    const key = `${preKey}${v}`
    if (typeof obj[v] === 'object') {
      flat(obj[v], `${key}.`, result)
    } else {
      result[key] = obj[v]
    }
  })
  return result
}

const flatResult = flat(entry, '', {})
console.log(flatResult)

/**
 * 2. 扁平化对象重组
 */
function restore(obj) {
  let result = {}

  Object.keys(obj).forEach((v) => {
    const list = v.split('.')
    const value = obj[v]
    list.reduce((res, item, index) => {
      if (index === list.length - 1) {
        res[item] = value
      } else {
        res[item] = res[item] ? res[item] : {}
      }
      return res[item]
    }, result)
  })
  return result
}

console.log(JSON.stringify(restore(flatResult), null, 4))

@XW666
Copy link

XW666 commented Sep 9, 2021

const find666 = (entry) => {

let map = {}
//递归方式
let func = (val, pname) => {
  for (key in val) {
    let kname = `${key}`
    if (pname) {
      kname = `${pname}.${key}`
    }
    if (typeof val[key] === 'object') {
      func(val[key], kname)
    } else {
      map[kname] = val[key]
    }
  }
}
func(entry)

}

@fenglizhu
Copy link

利用构造函数

function toObject(entry, output = {}, k_name = '') {
  for (let key in entry) {
    if (entry[key].constructor == Object){
      toObject(entry[key], output, k_name ? `${k_name}.${key}` :  `${key}`);
    }else{
      output[`${k_name}.${key}`] = entry[key];
    }
  }
  return output
}
toObject(entry)

@Joker-Qu
Copy link

回溯解决

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

function trans(obj) {
    const result = {};
    for (let k in obj) {
        backtrace([k])
    }
    function backtrace(trace) {
        let o = obj;
        for (let i = 0; i < trace.length; i++) {
            o = o[trace[i]]
        }
        if (typeof o !== 'object') {
            result[trace.join(',')] = o;
            return;
        }
        for (let k in o) {
            trace.push(k);
            backtrace(trace);
            trace.pop();
        }
    }
    return result;
}
console.log(trans(entry))

@Rain120
Copy link

Rain120 commented Feb 17, 2022

参考: Rain120/Web-Study#18

function flatten(obj) {
    var res = {};

    function flat(obj, key) {
        if (obj === null || Object(obj) !== obj) {
            res[key] = obj;
        } else if (Array.isArray(obj)) {
            var len = obj.length;
            if (len < 1) {
                res[key] = [];
                return;
            }

            for (var i = 0; i < len; i++) {
                flat(obj[i], key ? `${key}[${i}]` : key + '');
            }
        } else {
            for (var k in obj) {
                flat(obj[k], key ? `${key}.${k}` : k);
            }
        }
    }

    flat(obj, '');
    return res;
}

var obj = {
    a: {
        b: 1,
        c: 2,
        d: {
            e: 5
        }
    },
    b: [1, 3, {
        a: 2,
        b: 3
    }],
    c: 3
}

flatten(obj)

@Jesseszhang
Copy link

var entry = {
  a: {
   b: {
     c: {
       dd: 'abcdd'
     }
   },
   d: {
     xx: 'adxx'
   },
   e: 'ae'
  }
}
function flatObj(obj, preKey = '') {
  let res = {};
  for (let key in obj) {
    let value = obj[key];
    let newKey = preKey ? `${preKey}.${key}` : key;
    if (typeof obj[key] === 'object') {
      flatObj(obj[key], newKey)
    } else {
      res[newKey] = value;
    }
  }
}
console.log(flatObj(entry))

@gagalincheng
Copy link

function(tree){ const res = new Map() function main(tree, preKey = ''){ const keys = Object.keys(tree) for(let i = 0; i < keys.length; i++){ if(typeof tree[keys[i]] === 'object'){ main(tree[keys[i]], preKey ? ${preKey}.${keys[i]} : keys[i]) }else{ res.set(${preKey}.${keys[i]}, tree[keys[i]]) } } } main(tree) return res }

@negativeentropy9
Copy link

function format(obj) {
  const result = {};
  const acc = [];

  dfs(obj);

  return result;

  function dfs(r) {
    for (let key in r) {
      if (typeof r[key] !== "object") {
        result[[...acc].join(".") + "." + key] = r[key];
      } else {
        acc.push(key);
        dfs(r[key]);
        acc.pop();
      }
    }
  }
}

// output = {
// 'a.b.c.dd': 'abcdd',
// 'a.d.xx': 'adxx',
// 'a.e': 'ae'
// }
console.debug(
  format({
    a: {
      b: {
        c: {
          dd: "abcdd",
        },
      },
      d: {
        xx: "adxx",
      },
      e: "ae",
    },
  })
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests