skip to Main Content

Lets say I have the following array of objects which have parent child relations:

[
  { A1: [ "B1" ] },
  { B1: [ "C11", "C12", "C13" ] },
  { C11: [ "D100", "D111", "D112", "D113", "D131" ] },
  { D100: [ "E1000", "E1100" ] }
]

How can I convert the above array to a nested object to represent the relations?
So the target object would be:

{
A1: 
{
    B1:
    {
        C11: 
        {
            D100: ["E1000", "E1100"],
            D111: [],
            D112: [],
            D113: [],
            D131: []
        },
        C12: [],
        C13: []
    }
}

}

I tried several recursive approaches with reduce etc. but still struggle to get all levels converted correctly.

2

Answers


  1. Assuming an object with same pattern, you could takean object with references to the neste objects.

    If you like to get different values, like arrays instead of objects, you could specify this in the inout data.

    const
        data = [{ A1: ["B1"] }, { B1: ["C11", "C12", "C13"] }, { C11: ["D100", "D111", "D112", "D113", "D131"] }, { D100: ["E1000", "E1100"] }],
        result = data.reduce((r, o) => {
            Object
                .entries(o)
                .forEach(([k, a]) => a.forEach(l => (r[k] || r._)[l] ??= r[l] = {}));
            return r;
        }, { _: {} });
    
    console.log(result._);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  2. You can achieve the desired result using recursion. Maybe my example is a bit clunky, but it does the trick:

    const array = [
      { A1: [ "B1" ] },
      { B1: [ "C11", "C12", "C13" ] },
      { C11: [ "D100", "D111", "D112", "D113", "D131" ] },
      { D100: [ "E1000", "E1100" ] }
    ]
    
    // building a structure of objects
    
    const result = array.reduce((prev, current) => {
      Object.entries(current).map(([key, value]) => {
        if (value) {
          prev[key] = {};
          value.map(el => prev[key][el] = {});
        }
      });
      return prev;
    }, {})
    
    // loop and represent relations
    
    Object.values(result).map(value => {
      if (Object.keys(value).length) {
        represent(value, result);
      }
    })
    
    function represent(value, obj) {
      Object.keys(value).map(key => {
        if (obj[key]) {
          value[key] = { ...obj[key] };
          delete(obj[key]);
          represent(value[key], obj);
        }
      })
    }
    
    // convert and associate empty objects to array
    
    associate(result);
    
    function associate(obj) {
      Object.entries(obj).map(([key, value]) => {
        const values = Object.values(value).filter(o => Object.keys(o).length);
        if(values.length){
          associate(value)
        }else{
          if(Object.keys(value).length === 1) {
            obj[key] = [];
          }else {
            obj[key] = Object.keys(value);
          }
        }
      });
    }
    
    console.log(JSON.stringify(result, null, 2));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search