0

I have a Decision path tree which has nodes following a specific pattern i.e. decision -> reason -> decision -> outcome -> terminal. Every decision has a decisionId. Every path ends in a terminal state. The goal is collect all the decisions and aggregate them in a map of decisionId in a DecisionResult object. Every decision object starts with a root. Here is the structure for the types:

        export interface Root {
          rootId: string
          decision: Decision
        }
    
        export interface Option {
          optionName: string
          decision: Decision
        }
    
        export interface Decision {
          decisionId: string
          outcome?: Outcome
          options?: Option[]
       }
    
        export interface Outcome {
         terminal: Reason
        }
    
        export interface Reason {
         decision: Decision
        }

        export type DecisionResult = {
          rootId: string
          rootDecision:  Map<string, Decision>,
          decisions: Map<string, Decision>,
        }

Here is the JSON structure representing the data. I have no idea how to start navigating this structure. I start by getting the keys but don't know how to traverse the tree and add them to a map

   {
    "rootId": "decision-tree",
    "decision": {
    "decisionId": "rootOption",
    "options": [
     {
      "optionName": "LynsTheory",
      "decision": {
      "decisionId": "lynsOption",
      "outcome": {
        "terminal": "exit"
        }
      }
     },
     {
      "optionName": "Tensor",
       "decision": {
       "decisionId": "tensorOption",
       "outcome": {
        "reason": {
          "decision": {
            "decisionId": "terminalOption",
            "outcome": {
              "reason": {
                "terminal": "exit"
              }
            }
           }
          }
        }
      }
    },
    {
       "optionName": "Talend",
       "decision": {
       "decisionId": "optionals",
       "options": [
        {
          "optionName": "Bayes",
          "decision": {
            "decisionId": "talend",
            "options": [
              {
                "optionName": "cumulative",
                "decision": {
                  "decisionId": "cumulativeI",
                  "options": [
                    {
                      "optionName": "plus",
                      "decision": {
                        "decisionId": "plusT",
                        "outcome": {
                          "reason": {
                            "decision": {
                              "decisionId": "relational",
                              "outcome": {
                                "reason": "exit"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
]

} }

The resulting structure should look something like this: the keys are on the outside and every child decision is in its parent using the child key:

  {
   "rootId": "decision-tree",  
   "rootOption":{
   "root": {
    "decision": {
        "decisionId": "root",
        "outcome": {
          "terminal": "exit"
          }
        }
     }
  },
   "lynsOptions":{
    "decision": 
      {
     "decisionId": "lynsOptions",
     "optionName": "LynsTheory",
     "decisions": {
         "optionName": "LynsTheory",
         "Bayes": {
            "decision":{   
                "outcome":{
                    "terminal": "exit",
                    "reason": "Complete"        
                }                    
              }
         },
         "tensorOption":{
            "optionName": "TensorFlow",
            "decision":{   
                "outcome":{
                    "terminal": "exit",
                    "reason": "Complete"                       
                }                    
              } 
         },
         "variableOption":{
            "decision":{   
                "outcome":{
                    "terminal": "exit",
                    "reason": "Complete"                       
                }                    
              } 
         }
        }              
    }
  }     
}
Rahul Sharma
  • 5,562
  • 4
  • 24
  • 48
BreenDeen
  • 623
  • 1
  • 13
  • 42
  • Since I find it a bit confusing, could you provide a JSON that displays your desired outcome? – niklasbec Aug 14 '22 at 10:04
  • The structure is this export type DecisionResult = { rootId: string rootDecision: Map, decisions: Map, } – BreenDeen Aug 14 '22 at 20:08
  • The goal is to use the decisionIds as keys and the JSON object to be converted to a Decision object. the root has a Decision object and that is the root map. The Decision object types are in the post. I don't have an existing JSON string – BreenDeen Aug 14 '22 at 20:09
  • Those should be Records not Maps... in `DecisionResult`? The input is also missing two `}` at the end. Your output is also not consistent. In the output why is `lynsOptions` at the same level as `rootOption`? You'll need to address these inconsistencies and explain the process of obtaining the output from the input for someone to come up with an answer. – kelsny Aug 27 '22 at 03:59

1 Answers1

0

My head hurts just trying to understand what you are looking for!

I see several issues with your question that need to be address before someone can provide a sensible answer.


First, the expected output type of DecisionResult does not even match the json you provided as the expected output. See TS Playground. The resulting type error is...

Type '{ rootId: string; rootOption: { root: { decision: { decisionId: string; outcome: { terminal: string; }; }; }; }; lynsOptions: { decision: { decisionId: string; optionName: string; decisions: { optionName: string; Bayes: { ...; }; tensorOption: { ...; }; variableOption: { ...; }; }; }; }; }' is not assignable to type 'DecisionResult'.
  Object literal may only specify known properties, and '"rootOption"' does not exist in type 'DecisionResult'.

It's almost like you are looking to add the decisionId as keys on the root of the final output but the root decision has a different type than the others making the type even more confusing. Something like...

type DecisionResultTest =  & {
  rootId: string;
} & Record<string, Decision>;

Also note the inconsistency of typescript Record and Map types between the DecisionResult type and the expected output. I'm guessing this was just to show the expected output as JSON.

Second, your expected type keys and values are inconsistent with the input you provided namely:

  • Differing keys for 'lynsOption' vs 'lynsOptions'
  • Implied values for reason as 'Complete'
  • What seems to be some type of key interpolation from 'tensor' to 'tensorOption' and others
  • The 'variableOption' key comes out of nowhere

Third, your expected output has a non-obvious hierarchy of options. Somehow siblings of lynsOption are now children of lynsOptions in the output.

Fourth, arbitrary reconciliation of the root outcome as 'exit'. It seems like you are just providing the result of each nested decision but what happens if the final child outcomes are different.


If you would really like an answer please forget about the types and just provide an EXACT input and expected output. Along with a list of all assumptions such as interpolated key strings, implied values, etc. enough for someone to understand your expectations. The current input/output examples do not make sense!

Nickofthyme
  • 3,032
  • 23
  • 40
  • I'm sorry it isn't clear. I posed the question the question with the correct relationships for that part of the model that's simpler https://stackoverflow.com/questions/73452829/best-way-to-build-a-network-of-nodes-from-json-to-classes – BreenDeen Aug 25 '22 at 23:00
  • Ok perfect, I'll take a look – Nickofthyme Aug 25 '22 at 23:04