简体   繁体   中英

How to convert `pid` in json array into array of `children` form?

Raw array:

const data1 = [
  {
    id: 1,
    pid: 0
  },
  {
    id: 2,
    pid: 1
  },
  {
    id: 3,
    pid: 2
  }
]

How to convert pid in json array into array of children form?

How to turn him into:

[
  {
    id: 1,
    pid: 0,
    children: [
      {
        id: 2,
        pid: 1,
        children: [
          {
            id: 3,
            pid: 2
          }
        ]
      }
    ]
  }
]

-----------------------------------

He recognizes children by pid

How to write a function to do it?

thanks

 const data = [ { id: 1, pid: 0 }, { id: 4, pid: 3 }, { id: 2, pid: 1 }, { id: 3, pid: 2 } ]; function toTree (data) { data.forEach(function(item) { delete item.children; }); const map = {}; data.forEach(function(item) { map[item.id] = item; }); let val = []; data.forEach(function(item) { const parent = map[item.pid]; if(parent) { (parent.children || (parent.children = [])).push(item); } else { val.push(item); } }); return val; } console.log(JSON.stringify(toTree(data)));

Refer to @chiliNUT answer, add a method :

 const data1 = [ { id: 1, pid: 0 }, { id: 4, pid: 2 }, { id: 5, pid: 1 }, { id: 3, pid: 2 }, { id: 2, pid: 1 } ]; function toTree (data){ data.sort((a, b) => (a.pid - b.pid === 0) ? a.id - b.id : a.pid - b.pid); const map = {} data.forEach(item => (map[item.pid] || (map[item.pid] = []) ).push(item)) const mapArr = Object.values(map) mapArr.reduce((a, b, index, arr) => { if ( a[0].id === b[0].pid) { // There are still bugs here a[0].children = b } return b; }) return mapArr[0] } console.log(JSON.stringify(toTree(data1)));

data1.reduce((el1, el2)=>{el1.children = [el2]; return el2;});
const tree = [data1[0]];

You can use Array.reduce(el1, el2) It iterates over the array like map , except: For the first iteration, el1 and el2 are the first and second elements of the array, then for the iterations after, el1 is return value of the previous iteration, and el2 is the next element of the array. Unlike map, which operates on each element of the array, reduce uses each element of the array to generate a single return value.

data1.reduce((el1, el2)=>{el1.children = [el2]; return el2;});

So that appends all elements of data1 successively to the first element. Your final output should be an array, so

const tree = [data1[0]]

Follow up: if the data is not already sorted by id, you can sort it like this

data1.sort((el1, el2) => {return el1.id > el2.id ? 1 : -1});

 const data1 = [ { id: 1, pid: 0 }, { id: 2, pid: 1 }, { id: 3, pid: 2 } ] data1.reduce((a,b)=>{a.children=[b];return b;}); const tree = [data1[0]]; console.log(tree);

I think the best way is to use recursive to loop on each element and put as child of the previous one.

const data1 = [
  {
    id: 1,
    pid: 0
  },
  {
    id: 2,
    pid: 1
  },
  {
    id: 3,
    pid: 2
  }
];

function convert(arr){
    let counter = 0;
  let convertedArray = [];

  function recursiveFunction(currentObject = null){
            if(counter >= arr.length)   return convertedArray;

      if(currentObject == null){
      currentObject = {
        children: [arr[0]]
        }
        convertedArray.push(currentObject);
      } else {  
        currentObject.children = [ arr[counter] ];
      }


      counter++;

      return recursiveFunction(currentObject.children[0]);   
    }

  return recursiveFunction();

}


let newData = convert(data1);

console.log(newData);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM