undefinedfix
Sign in

How to convert the data format of array object into tree structure?

mathsteck edited in Wed, 25 Jan 2023

The following data are available:

var init_data = [
  {
    "parent_ind":"女装",
    "name":"连衣裙"
  },
  {
    "parent_ind":"女装"
  },
  {
    "parent_ind":"女装",
    "name":"半身裙"
  },
  {
    "parent_ind":"女装",
    "name":"A字裙"
  },
  {
    "name":"数码"
  },
  {
    "parent_ind":"数码",
    "name":"电脑配件"
  },
  {
    "parent_ind":"电脑配件",
    "name":"内存"
  },
];

To convert to the following tree structure:

{
  "数码":{
    "电脑配件":{
      "内存":{}
    }
  },
  "女装":{
    "连衣裙":{},
    "半身裙":{},
    "A字裙":{}
  }
}

How to write a function?

4 Replies
AminBouali
commented on Wed, 25 Jan 2023
function convert2tree(data) {
    var store = {};
    var result = {};

    data.forEach(item => {
        if (item.hasOwnProperty('name')) {
            if (item.hasOwnProperty('parent_ind')) {
                var name = item.name;
                var parent_ind = item.parent_ind;

                if (store[parent_ind]) {
                    if (!store[name]) {
                        store[name] = `${store[parent_ind]}-${name}`;
                    }
                } else {
                    store[parent_ind] = parent_ind;
                    store[name] = `${parent_ind}-${name}`;
                }
            } else {
                var name = item.name;

                if (!store[name]) {
                    store[name] = name;
                }
            }
        }
    });

    Object
    .entries(store)
    .sort((a, b) => [...a[1].matchAll('-')].length - [...b[1].matchAll('-')].length)
    .forEach(([key, value]) => {
        if (value.includes('-')) {
            var target = result;
            var ks = value.split('-');

            for (let i = 0, len = ks.length; i < len; i++) {
                if (i < len - 1) {
                    target = target[ks[i]];
                } else {
                    target[ks[i]] = {};
                }
            }
        } else {
            result[key] = {};
        }
    });

    return result;
}
prufal
commented on Thu, 26 Jan 2023
function transformTree(arr) {
  let result = {};
  const newValue = arr.filter(item => item.parent_ind && item.name)
  newValue.forEach(item => {
    if (result[item.parent_ind]) {
      result[item.parent_ind][item.name] = {}
    } else {
      result[item.parent_ind] = {};
      result[item.parent_ind][item.name] = {}
    }
  })
  return result;
}

Demo link: https://codepen.io/liangxh052...

hbyqn
commented on Thu, 26 Jan 2023
function format(data){
    let res = {};
    let nameBasedParent = [];
    data.map(val=>{
        if( val.parent_ind && val.name && nameBasedParent.indexOf(val.name)<0 ){
            nameBasedParent.push(val.name);
        }   
        return val             
    }).map(val=>{
        if(
            !res[val["parent_ind"]] 
            && val["parent_ind"] 
            && nameBasedParent.indexOf(val["parent_ind"])==-1
        ){
            res[val["parent_ind"]]={};
        }
        return val;
    }).filter(val=>val.parent_ind && val.name)
    .map(val=>{
        if( nameBasedParent.indexOf(val.parent_ind)==-1 ){
            res[val.parent_ind][val.name]={}
        }
        else if(nameBasedParent.indexOf(val.parent_ind)!=-1){
            data.forEach(item=>{
                if(item.name == val.parent_ind){
                    res[item.parent_ind][item.name][val.name]={}
                }
            })
        }
    })

    console.log(res);
    return res;
}

I wrote it myself. I think it's too troublesome, there are many loops, and the data changes (such as init)_ Add another {"parent" to data_ This function doesn't work. Is there a better way to make a general function.

user3856212
commented on Thu, 26 Jan 2023

It looks like loop plus recursion