How to map recursively children when you only have a multi decimal [duplicate]

Solution 1:

You could take an empty path as special case take { status: 'full' } as new value.

Then reduce the keys and assign a default new object, if not exist and return subOptions for each loop.

Finally assign the value.

function setValue(object, path, value) {
    var last = path.pop();

    if (!path.length) {
        value = { status: 'full' };
    }

    path.reduce(
        (o, k) => (o[k] = o[k] || { status: 'limited', subOptions: {} }).subOptions,
        object
    )[last] = value;
}

const
    values = { home: true, financials: true, products_edit: true, products_create: true, orders_delete: true, pages_category_create: true },
    result = {};

Object.entries(values).forEach(([k, v]) => setValue(result, k.split('_'), v));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Solution 2:

This is how I would do it, probably could be optimized.

Combination of Object.keys and Array#reduce.

const sampleObj = { 
  home: true,
  products_edit: true,
  products_create: true,
  orders_delete: true,
  pages_category_create: true
}

const res = Object.keys(sampleObj).reduce((acc,cur)=>{
  const value = sampleObj[cur];
  const tree  = cur.split("_");
  const root  = tree.shift();
  
  if(!acc[root]){
    acc[root] = {};
    if(tree.length === 0){
       acc[root].status = "full"
       return acc;
    } else {
       acc[root].subOptions = {};
       acc[root].status = "limited";
    }
  }
  
  acc[root].subOptions[tree.shift()] = tree.reverse().reduce((acc,cur)=>{
      return {[cur]:acc}
  }, value);
  return acc;
  
}, {});

console.log(res);