Convert object into specific format with recursive function

半世苍凉 提交于 2021-01-29 21:33:01

问题


original object : [ { Name: 'ZoneName', Value: 'Box A', } , { Name: 'AirSide', Value: { JZCleanTipFlowResults: { LeakageAirFlowRate: 2.0519336991674058, LeakageAirFlowRate_Uncertainty: 0.05755421849942835, LeakageAirFlowRate_lbmhr: 16285.188088630204, LeakageAirFlowRate_lbmhr_Uncertainty: 456.779511900225, }, UsedAmbientTemperatureForCombustion: true, SubStoichWarning: false, }, } , { Name: 'FuelSide', Value: { Fuels: { 'Header 0': { CleanTipResults: { HR: 10776333.422366736, HR_Uncertainty: 14383.420657232984, HR_MMBTUhr: 36.77037592294784, }, }, }, CleanTipResults: { HR: 10776333.422366736, HR_Uncertainty: 14383.420657232984, }, }, }, ];

Want object like :

denested shape :[ { Name: 'ZoneName', Value: 'Box A', } , { Name: 'AirSide|JZCleanTipFlowResults|LeakageAirFlowRate', Value: 2.0519336991674058, } , { Name: 'AirSide|JZCleanTipFlowResults|LeakageAirFlowRate_Uncertainty', Value: 0.05755421849942835, } , { Name: 'AirSide|JZCleanTipFlowResults|LeakageAirFlowRate_lbmhr', Value: 16285.188088630204, } , { Name: 'AirSide|JZCleanTipFlowResults|LeakageAirFlowRate_lbmhr_Uncertainty', Value: 456.779511900225, } , { Name: 'AirSide|UsedAmbientTemperatureForCombustion', Value: true, } , { Name: 'AirSide|JZCleanTipFlowResults|SubStoichWarning', Value: false, } , { Name: 'FuelSide|Fuels|Header 0|CleanTipResults|HR', Value: 10776333.422366736, } , { Name: 'FuelSide|Fuels|Header 0|CleanTipResults|HR_Uncertainty', Value: 14383.420657232984, } , { Name: 'FuelSide|Fuels|Header 0|CleanTipResults|HR_MMBTUhr', Value: 36.77037592294784, } , { Name: 'FuelSide|CleanTipResults|HR', Value: 10776333.422366736, } , { Name: 'FuelSide|CleanTipResults|HR_Uncertainty', Value: 14383.420657232984, } ]


回答1:


I will supply my thoughts since there is already a high-quality answer here. But please, in the future, StackOverflow is meant to help you when you get stuck, not to write your code for you. Please demonstrate your own effort and explain where you got stuck.

I stole helper functions from previous answers of mine. path takes an array of node names and an object and returns the value at that path in the object, or undefined if any node doesn't exist. For instance, path (['foo', 'bar', 'baz']) applied to {foo: {bar: {baz: 42}, qux: 99}, corge: -1} yields 42.

getPaths is a generator function giving you the paths to the leaf nodes of an object. So getPaths ({foo: {bar: {baz: 42}, qux: 99}, corge: -1}) yields ["foo", "bar", "baz"], then ["foo", "qux"], and ["corge"].

A custom transform function iterates over your array of Name/Value pairs, just returning them if Value is a string and otherwise using getPaths to turn the value into an array of Condensed|Path|Names / Value pairs. These are joined into a single list with flatMap.

const path = (ps = [], obj = {}) =>
  ps .reduce ((o, p) => (o || {}) [p], obj)

function * getPaths(o, p = []) {
  if (Object(o) !== o || Object .keys (o) .length == 0) yield p 
  if (Object(o) === o)
    for (let k of Object .keys (o))
      yield * getPaths (o[k], [...p, Number.isInteger (Number (k)) ? Number (k) : k])
}

const transform = (orig) => 
  orig .flatMap (({Name, Value}) => 
    typeof Value == 'string' 
      ? {Name, Value}
      : [... getPaths (Value)] .map (
          route => ({Name: Name + '|' + route .join ('|'), Value: path (route, Value)})
        )
  )

const orig = [{Name: "ZoneName", Value: "Box A"}, {Name: "AirSide", Value: {JZCleanTipFlowResults: {LeakageAirFlowRate: 2.0519336991674058, LeakageAirFlowRate_Uncertainty: .05755421849942835, LeakageAirFlowRate_lbmhr: 16285.188088630204, LeakageAirFlowRate_lbmhr_Uncertainty: 456.779511900225}, UsedAmbientTemperatureForCombustion: true, SubStoichWarning: false}}, {Name: "FuelSide", Value: {Fuels: {"Header 0": {CleanTipResults: {HR: 10776333.422366736, HR_Uncertainty: 14383.420657232984, HR_MMBTUhr: 36.77037592294784}}}, CleanTipResults: {HR: 10776333.422366736, HR_Uncertainty: 14383.420657232984}}}];

console .log (transform (orig))
.as-console-wrapper {min-height: 100% !important; top: 0}



回答2:


If you're just looking for a copy/paste answer, I won't bother supplying much of an explanation. But I don't mind completing the puzzle and sharing my work -

  1. If the input is an object,
  2. "Flatten" it.
  3. Otherwise, the input is not an object. Return the "flat" result.

const transform = (o = {}, path = []) =>
  Object(o) === o   // 1
    ? Object        // 2
        .entries(o)
        .flatMap(([ k, v ]) => transform(v, [...path, k]))
    : [ { path: path.join("|"), value: o } ] // 3

const data =
  [{Name:'ZoneName',Value:'Box A'},{Name:'AirSide',Value:{JZCleanTipFlowResults:{LeakageAirFlowRate:2.0519336991674058,LeakageAirFlowRate_Uncertainty:0.05755421849942835,LeakageAirFlowRate_lbmhr:16285.188088630204,LeakageAirFlowRate_lbmhr_Uncertainty:456.779511900225},UsedAmbientTemperatureForCombustion:true,SubStoichWarning:false}},{Name:'FuelSide',Value:{Fuels:{'Header 0':{CleanTipResults:{HR:10776333.422366736,HR_Uncertainty:14383.420657232984,HR_MMBTUhr:36.77037592294784}}},CleanTipResults:{HR:10776333.422366736,HR_Uncertainty:14383.420657232984}}}]

const result =
  transform(data)

console.log(JSON.stringify(result, null, 2))

Output -

[
  {
    "path": "0|Name",
    "value": "ZoneName"
  },
  {
    "path": "0|Value",
    "value": "Box A"
  },
  {
    "path": "1|Name",
    "value": "AirSide"
  },
  {
    "path": "1|Value|JZCleanTipFlowResults|LeakageAirFlowRate",
    "value": 2.0519336991674058
  },
  {
    "path": "1|Value|JZCleanTipFlowResults|LeakageAirFlowRate_Uncertainty",
    "value": 0.05755421849942835
  },
  {
    "path": "1|Value|JZCleanTipFlowResults|LeakageAirFlowRate_lbmhr",
    "value": 16285.188088630204
  },
  {
    "path": "1|Value|JZCleanTipFlowResults|LeakageAirFlowRate_lbmhr_Uncertainty",
    "value": 456.779511900225
  },
  {
    "path": "1|Value|UsedAmbientTemperatureForCombustion",
    "value": true
  },
  {
    "path": "1|Value|SubStoichWarning",
    "value": false
  },
  {
    "path": "2|Name",
    "value": "FuelSide"
  },
  {
    "path": "2|Value|Fuels|Header 0|CleanTipResults|HR",
    "value": 10776333.422366736
  },
  {
    "path": "2|Value|Fuels|Header 0|CleanTipResults|HR_Uncertainty",
    "value": 14383.420657232984
  },
  {
    "path": "2|Value|Fuels|Header 0|CleanTipResults|HR_MMBTUhr",
    "value": 36.77037592294784
  },
  {
    "path": "2|Value|CleanTipResults|HR",
    "value": 10776333.422366736
  },
  {
    "path": "2|Value|CleanTipResults|HR_Uncertainty",
    "value": 14383.420657232984
  }
]


来源:https://stackoverflow.com/questions/61266520/convert-object-into-specific-format-with-recursive-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!