繁体   English   中英

参照父对象展平嵌套对象

[英]Flattening nested objects with reference to parent object

我想整理以下内容

let o = {
  name: "John",
  school: {
    name: "Phillps",
  }
};

至:

{
  name: "John",
  schoolName: "Phillps"
}

我的代码看起来像这样

f= Object.assign({}, ..._flatten(o));

function _flatten(o) {
  return [].concat(
    ...Object.keys(o).map(k =>
      typeof o[k] === "object" ? _flatten(o[k]) : { [k]: o[k] }
    )
  );
}

这产生

{  
 name: "Phillps"
}

如您所见,它不能处理嵌套对象中属性名称的冲突。 即学生的名字被学校的名字覆盖。 是否可以修改代码,以便将深色属性以其父对象名称作为前缀?

您可以使用Object.entriesArray.prototype.flatMapObject.fromEntries

 const upperFirst = (str = "") => str[0] .toUpperCase () + str.substr(1) const camelCase = ([ first = "", ...rest ]) => first + rest .map (upperFirst) .join ('') const append = (xs, x) => xs .concat ([ x ]) const flatten = (o = {}) => { const loop = (o, path) => Object (o) === o ? Object .entries (o) .flatMap ( ([ k, v ]) => loop ( v , append (path, k) ) ) : [ [ camelCase (path), o ] ] return Object .fromEntries (loop (o, [])) } console.log ( flatten ( { name: "John" , school: { name: "Phillips" , district: { zone: 1 } } } ) ) // { "name": "John" // , "schoolName": "Phillips" // , "schoolDistrictZone": 1 // } 

flatMap急切地评估输入并创建一些中间值,然后再返回flatten 因为Object.fromEntries接受任何迭代,所以最好用生成器编写loop

const flatten = (o = {}) =>
{ const loop = function* (o, path)
  { if (Object (o) === o)
      for (const [ k, v ] of Object .entries (o))
        yield* loop
          ( v
          , append (path, k)
          )
    else
      yield [ camelCase (path), o ]
  }
  return Object .fromEntries (loop (o, []))
}

重新运行该程序,您将看到完全相同的输出。 还值得一提的是两个程序之间的结构相似性。

您可以使用相同的代码,只需将前缀作为参数传递给_flatten() 求助时,将前缀与当前父键连接起来。 随着嵌套的深入,这将继续添加前缀:

 function _flatten(o, prefix="") { return [].concat( ...Object.keys(o).map(k => typeof o[k] === "object" ? _flatten(o[k], prefix+k) : { [prefix+k]: o[k] } ) ); } let o = { name: "John", school: { name: "Phillps", } }; f= Object.assign({}, ..._flatten(o)); console.log(f) 

此外,您可以简单地使用reduce()Object.assign编写代码,而不是使用[].concact()创建数组

 function _flatten(o, prefix = "") { return Object.keys(o).reduce((obj, k) => Object.assign(obj, typeof o[k] === "object" ? _flatten(o[k], prefix + k) : { [prefix + k]: o[k]}) , {}) } let o = { name: "John", school: { name: "Phillps", } }; f = _flatten(o); console.log(f) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM