0

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, } ]

  • 2
    Welcome to Stack Overflow! Please take the [tour] (you get a badge!) and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) Your best bet here is to do your research, [search](/help/searching) for related topics on SO, and give it a go. ***If*** you get stuck and can't get unstuck after doing more research and searching, post a [mcve] of your attempt and say specifically where you're stuck. People will be glad to help. – T.J. Crowder Apr 17 '20 at 07:49
  • When you were asking your question, there was a big orange **How to Format** box to the right of the text area with useful info in it. There was also a toolbar full of formatting aids. And a **[?]** button giving formatting help. *And* a preview area showing what your post would look like when posted, between the text area and the Post Your Question button (so that you'd have to scroll past it to find the button, so you'd look at it). Making your post clear, and showing that you took the time to do so, improves your chances of getting good answers. – T.J. Crowder Apr 17 '20 at 07:50
  • People really are willing to help; T.J Crowder was telling it truly. But you need to do your part first. What have you tried? Where are you stuck? – Scott Sauyet Apr 17 '20 at 16:25

2 Answers2

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}
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Nope, I don't particularly like typescript and use it only when absolutely forced to do so. Even the request demonstrates that you still don't understand what StackOverflow is about, though. Please read the links in the first comment to your question. This is not a code-writing service. It's a Q & A site for programming topics. People do want to help, but only if you're willing to put in the requisite work. – Scott Sauyet Apr 21 '20 at 13:51
0

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
  }
]
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • No, because your data is not well-typed. Even if I gave you the valid TS for this program, it would still be bad. Adding TS to this would be like saying "I have bad data, but I want to use TS to be 100% sure it's bad." – Mulan Apr 21 '20 at 16:47
  • You didn't put up an attempt of your own, so it's hard to measure how much you've invested in solving the problem on your own. To that end, the only other advice I have for you is _not_ to convert it to TS. If you want type safety in JS, I would be looking at the more future-proof tools like ReasonML. – Mulan Apr 21 '20 at 16:50