Home > Software design >  Convert a list of objects with paths to a nested hierarchy structure
Convert a list of objects with paths to a nested hierarchy structure

Time:12-19

This is my input:

[
   {
      "id":360006927051,
      "name":"KBVSA::Agent",
      "raw_name":"KBVSA::Agent",
      "value":"kbvsa__agent",
      "default":false
   },
   {
      "id":360006927071,
      "name":"KBVSA::Agent Procedure",
      "raw_name":"VSA::Agent Procedure",
      "value":"vsa__agent_procedure",
      "default":false
   },
   {
      "id":360006927091,
      "name":"KBVSA::Anti-Malware",
      "raw_name":"KBVSA::Anti-Malware",
      "value":"kbvsa__anti-malware",
      "default":false
   },
   {
      "id":360006927111,
      "name":"KMTraverse::Devices",
      "raw_name":"KMTraverse::Devices",
      "value":"kmtraverse__devices",
      "default":false
   },
   {
      "id":360006927131,
      "name":"KMTraverse::Signatures",
      "raw_name":"KMTraverse::Signatures",
      "value":"kmtraverse_signatures",
      "default":false
   },
   {
      "id":360006927151,
      "name":"MCBMS::HR",
      "raw_name":"MCBMS::HR",
      "value":"mcbms__hr",
      "default":false
   },
   {
      "id":360006927171,
      "name":"MCBMS::Finance",
      "raw_name":"MCBMS::Finance",
      "value":"mcbms__finance",
      "default":false
   },
   {
      "id":360006927191,
      "name":"TMONAuthAnvil::On-Demand::2FA",
      "raw_name":"TMONAuthAnvil::On-Demand::2FA",
      "value":"tmonauthanvil__on-demand__2fa",
      "default":false
   },
   {
      "id":360006927211,
      "name":"TMONAuthAnvil::On-Premise::2fa",
      "raw_name":"TMONAuthAnvil::On-Premise::2fa",
      "value":"tmonauthanvil__on-premise__2fa",
      "default":false
   },
   {
      "id":360006927231,
      "name":"KYUnigma::Monitor",
      "raw_name":"kyUnigma::Monitor",
      "value":"kyunigma__monitor",
      "default":false
   },
   {
      "id":360006927251,
      "name":"KYUnigma::Report",
      "raw_name":"kyUnigma::Report",
      "value":"kyunigma__report",
      "default":false
   },
   {
      "id":360006927271,
      "name":"2365 Command::Monitor",
      "raw_name":"365 Command::Monitor",
      "value":"365_command__monitor",
      "default":false
   },
   {
      "id":360006927291,
      "name":"2365 Command::Report",
      "raw_name":"2365 Command::Report",
      "value":"2365_command__report",
      "default":false
   }
]

This is the output I am trying to get from it:

[
   {
      "label":"-",
      "value":""
   },
   {
      "label":"KBVSA",
      "options":[
         {
            "label":"Agent",
            "value":"kbvsa__agent"
         },
         {
            "label":"Agent Procedure",
            "value":"vsa__agent_procedure"
         },
         {
            "label":"Anti-Malware",
            "value":"vsa__anti-malware"
         }
      ]
   },
   {
      "label":"KMTraverse",
      "options":[
         {
            "label":"Devices",
            "value":"kmtraverse__devices"
         },
         {
            "label":"Signatures",
            "value":"kmtraverse_signatures"
         }
      ]
   },
   {
      "label":"MCBMS",
      "options":[
         {
            "label":"HR",
            "value":"mcbms__hr"
         },
         {
            "label":"Finance",
            "value":"mcbms__finance"
         }
      ]
   },
   {
      "label":"TMONAuthAnvil",
      "options":[
         {
            "label":"On-Demand",
            "options":[
               {
                  "label":"2FA",
                  "value":"tmonauthanvil__on-demand__2fa"
               }
            ]
         },
         {
            "label":"On-Premise",
            "options":[
               {
                  "label":"2fa",
                  "value":"tmonauthanvil__on-premise__2fa"
               }
            ]
         }
      ]
   },
   {
      "label":"KYUnigma",
      "options":[
         {
            "label":"Monitor",
            "value":"kyunigma__monitor"
         },
         {
            "label":"Report",
            "value":"kyunigma__report"
         }
      ]
   },
   {
      "label":"23365 Command",
      "options":[
         {
            "label":"Monitor",
            "value":"365_command__monitor"
         },
         {
            "label":"Report",
            "value":"365_command__report"
         }
      ]
   }
]

I'm trying to create a new array and push it to data like this. But I'm not able to make the exact output Array Name split ("::"), and distinguish between the first name(s), that is/are common, and the new label's value as sub arrays.

I'm trying to make a select option design where a single select will show multiple related values.

CodePudding user response:

You could create a Map keyed by "path" (i.e. a "::"-delimited string), and map each key to a target node you have created for that key.

As you iterate the labels that make up a path, look up the corresponding partial path in that map, and if it doesn't exist yet, create the target object for it (with a label property), and include it in the parent's options property. That parent is the node that was retrieved/created in the previous iteration of this path traversal.

When the iteration of a path is complete, attach the value property to the last node that was created in that traversal.

As the entry { label: "-", value: "" } has no backing source in your input data, I just hard-coded it as an initialisation step. I didn't get clarification when I asked about it.

Here is an implementation:

function convert(data) {
    const map = new Map;
    const root = { options: [{ label: "-", value: "" }] };
    for (const {name, value} of data) {
        let path = "";
        let parent = root;
        for (const label of name.split("::")) {
            path  = "::"   label;
            let node = map.get(path);
            if (!node) {
                map.set(path, node = { label });
                (parent.options ??= []).push(node);
            }
            parent = node;
        }
        parent.value = value;
    }
    return root.options;
}

const data = [{"id":360006927051,"name":"KBVSA::Agent","raw_name":"KBVSA::Agent","value":"kbvsa__agent","default":false},{"id":360006927071,"name":"KBVSA::Agent Procedure","raw_name":"VSA::Agent Procedure","value":"vsa__agent_procedure","default":false},{"id":360006927091,"name":"KBVSA::Anti-Malware","raw_name":"KBVSA::Anti-Malware","value":"kbvsa__anti-malware","default":false},{"id":360006927111,"name":"KMTraverse::Devices","raw_name":"KMTraverse::Devices","value":"kmtraverse__devices","default":false},{"id":360006927131,"name":"KMTraverse::Signatures","raw_name":"KMTraverse::Signatures","value":"kmtraverse_signatures","default":false},{"id":360006927151,"name":"MCBMS::HR","raw_name":"MCBMS::HR","value":"mcbms__hr","default":false},{"id":360006927171,"name":"MCBMS::Finance","raw_name":"MCBMS::Finance","value":"mcbms__finance","default":false},{"id":360006927191,"name":"TMONAuthAnvil::On-Demand::2FA","raw_name":"TMONAuthAnvil::On-Demand::2FA","value":"tmonauthanvil__on-demand__2fa","default":false},{"id":360006927211,"name":"TMONAuthAnvil::On-Premise::2fa","raw_name":"TMONAuthAnvil::On-Premise::2fa","value":"tmonauthanvil__on-premise__2fa","default":false},{"id":360006927231,"name":"KYUnigma::Monitor","raw_name":"kyUnigma::Monitor","value":"kyunigma__monitor","default":false},{"id":360006927251,"name":"KYUnigma::Report","raw_name":"kyUnigma::Report","value":"kyunigma__report","default":false},{"id":360006927271,"name":"2365 Command::Monitor","raw_name":"365 Command::Monitor","value":"365_command__monitor","default":false},{"id":360006927291,"name":"2365 Command::Report","raw_name":"2365 Command::Report","value":"2365_command__report","default":false}];
const result = convert(data);
console.log(result);

  • Related