Home > Software engineering >  Javascript Object mapping, creating parent child relationship to form a object
Javascript Object mapping, creating parent child relationship to form a object

Time:12-22

Struggling with the logic: Trying my best to explain it. I have an array of objects like:

[
{ categoryPath: "client/client one/client two" description: "test description"},
{ categoryPath: "client/client one" description: "test description"},
{ categoryPath: "research/research one" description: "test description"}
]

EDIT: the expected output, I did a mistake in the expected output. The client One category should have two attributes, as in the input Object, we can see that it second object has categoryPath as, client/client one- so the description of this should come under the client one hierarchy.

my need is to convert it into an array of objects like the below:

[{
  categoryName: 'client',
  categoryId: '0',
  subcategories: [
    {
      categoryId: '1',
      categoryName: 'client one',
      subcategories: [{
        categoryId: '2',
        categoryName: 'client two',
        attributes: [
          {
            description: 'test description '
          }],
      }],
      attributes: [{
            description: 'test description '
          },
          {
            description: 'test description '
          }    ]
    },
  ],
  attributes: []
},
{
  categoryName: 'research',
  categoryId: '0',
  subcategories: [
    {
      categoryId: '1',
      categoryName: 'research one',
        attributes: [
          {
            description: 'test description '
          }],
      }],
    },
  ],
  attributes: []
},

The code which I have written is keep getting complex, not sure if you'll get it, but here: But if you check my code it is returning the circular array issue, and nesting the parent categories in the object.

let baseObj = {
    name : '',
  parentName:'',
  subCat: [],
  att: [],
  level: 0,
}
let masterObj = {};
let baseId = {};
for (let i = 0; i < arr.length; i  ) {
   //console.log(arr[i]);
   let splitCat = arr[i].cat.split('/');
   let addAttData = [...splitCat, {att:arr[i].name}];
   if (!masterObj[splitCat[0]]) {
    masterObj[splitCat[0]] = {...baseObj};
    masterObj[splitCat[0]].name = splitCat[0];
   }
   getParentRec(splitCat[0], addAttData, masterObj);
}
console.log(JSON.stringify(masterObj,null,2));
Object.keys(masterObj).forEach((item, index) => {
    //client//research level
  console.log('new', item, masterObj[item]);
    for(let i = masterObj[item].level ; i> 0; i--) {
    console.log(i, 'item', masterObj[item].level);
    let obj = getObj(masterObj[item]);
    console.log('obj', obj);
    console.log('whole fir',masterObj[item]);
    obj.forEach((objItem) => {
    let prName = masterObj[item][objItem].parentName;
    console.log('current', masterObj[item][objItem]);
    if (prName !== item) { 
    let newObj = {...masterObj[item][objItem]};
        masterObj[item][prName].subCat.push(newObj);
      console.log('v',prName, masterObj[item][prName]);             delete masterObj[item][objItem];
      console.log('after delete', masterObj[item][objItem]);
    console.log('whole',masterObj[item]);
    } else {
      console.log('masterItem', masterObj[item]);
        masterObj[item].subCat.push(masterObj[item][objItem]);
      console.log(item, 'final',JSON.stringify(masterObj[item], null, 2));
    }  
    
    })
    masterObj[item].level = masterObj[item].level - 1;
  }
})

//console.log(JSON.stringify(masterObj, null, 2));

function getObj (obj) {
console.log(Object.keys(obj), obj.level);
let objFound= Object.keys(obj).filter(filterItem => obj[filterItem].level === obj.level);
console.log('found', obj[objFound]);
return objFound;
}

function getParentRec(parentId, arrObj, masterObj) {
    //console.log('start', masterObj);
    for (let i = 1; i< arrObj.length - 1 ;i  ) {
        let obj = {...baseObj};
      //console.log('obj', obj);
       let lastObj = '';
      lastObj = arrObj[i];
      obj.name = lastObj;
      if ( i 1 === arrObj.length - 1) {
        obj.att = [arrObj[arrObj.length - 1]];
      }
      obj.parentName = arrObj[i -1];
      obj.level = i;
      /* console.log('l', lastObj, i);
      console.log('iobj', obj);
      console.log('as ',masterObj[parentId][lastObj]); */
      if (!masterObj[parentId][lastObj]) {
        //console.log('wo', i);
        masterObj[parentId][lastObj] = obj;
        if (i >=  masterObj[parentId].level) {
         masterObj[parentId].level = i;
        }
        //console.log('masterObj', masterObj);
      }
      
  }
  return masterObj;
}

Please help with the logic, it is for creating a folder expand like UI in react. So anything which is having a similar parent category will appear in that hierarchy. Else it will form a new hierarchy like research. But in the case of the client is getting inside the parent category client and creating hierarchy like at the sibling level.

CodePudding user response:

Try this one with Array.reduce

const data = [{ categoryPath: "client/client one/client two", description: "test description"},{ categoryPath: "client/client one", description: "test description"},{ categoryPath: "research/research one", description: "test description"}];

const transforming = data.reduce((acc, {categoryPath, description}) => {
  const leaf = categoryPath.split('/').reduce((parent, categoryName, index) => {
    acc[categoryName] = acc[categoryName] || {
      categoryId: index.toString(),
      categoryName: categoryName,
      subcategories: [],
      attributes: []
    };
    if (!acc[parent].subcategories.find(child => child.categoryName === categoryName)) {
      acc[parent].subcategories.push(acc[categoryName]);
    }
    return categoryName;
  }, '-');
  acc[leaf].attributes.push({description});
  return acc;
}, { '-': { subcategories: [] } });

const result = transforming['-'].subcategories;

console.log(JSON.stringify(result));

Edit

const data = [{ categoryPath: "client/client one/client two", description: "test description"},{ categoryPath: "client/client one", description: "test description"},{ categoryPath: "research/research one", description: "test description"}];

const transforming = data.reduce((acc, {categoryPath, description}) => {
  categoryPath.split('/').reduce((parent, categoryName, index) => {
    acc[categoryName] = acc[categoryName] || {
      categoryId: index.toString(),
      categoryName: categoryName,
      subcategories: [],
      attributes: []
    };
    if (index > 0) {
      acc[categoryName].attributes.push({description})
    }
    if (!acc[parent].subcategories.find(child => child.categoryName === categoryName)) {
      acc[parent].subcategories.push(acc[categoryName]);
    }
    return categoryName;
  }, '-');
  return acc;
}, { '-': { subcategories: [] } });

const result = transforming['-'].subcategories;

console.log(JSON.stringify(result));

  • Related