On the Recursive problem js

original data format

let obj =[
        {1:"20190805",2:"1",3:"success"},
        {1:"20191120",2:"1.1",3:"success"},
        {1:"20190212",2:"1.1.1",3:"success"},
        {1:"20190212",2:"1.1.2",3:"success"},
        {1:"20190212",2:"1.1.3",3:"success"},
        {1:"20190212",2:"1.2",3:"success"},
        {1:"20190212",2:"1.2.1",3:"success"},
        {1:"20190212",2:"2",3:"success"},
        {1:"20190212",2:"2.1",3:"success"},
        {1:"20190212",2:"2.2.1",3:"success"},
        {1:"20190212",2:"2.2",3:"success"},
        {1:"20190212",2:"2.3",3:"success"},
        {1:"20190212",2:"2.3.1",3:"success"},
        ...
        ]

finally, I want the following result format. How can I achieve it

?
let data = [
        {1: "20190805", 2: "1", 3: "success", children: [
            {1: "20191120", 2: "1.1", 3: "success", children: [
                {1: "20190212", 2: "1.1.1", 3: "success"},
                {1: "20190212", 2: "1.1.2", 3: "success"},
                {1: "20190212", 2: "1.1.3", 3: "success"},
            ]}, {1: "20191120", 2: "1.2", 3: "success", children: [
                    {1: "20190212", 2: "1.2.1", 3: "success"},
                ]
            }]
        },
        {1: "20190212", 2: "2", 3: "success", children: [
            {1: "20190212", 2: "2.1", 3: "success", children: [
                {1: "20190212", 2: "2.2.1", 3: "success"},
            ]},
            {1: "20190212", 2: "2.2", 3: "success"},
            {1: "20190212", 2: "2.3", 3: "success", children: [
                {1: "20190212", 2: "2.3.1", 3: "success"}]
            }]
        },
        ...
    ]
May.28,2022

/**
 *
 * @param {Array} source
 * @returns {Array} 
 */
function mark(source) {
  var temp = {};
  source.forEach(item => {
    temp[item["2"]] = item;
  });
  source.forEach(item => {
    var key = item["2"],
      parent;
    //
    if (key.length > 1) {
      // id
      key = key.slice(0, -2);
      parent = temp[key];
      if (parent) {
        parent.children = parent.children || [];
        parent.children.push(item);
      }
    }
  });
  return Object.keys(temp).reduce((ret, key) => ret.concat(key.length === 1 ? temp[key] : []), []);
}


the code on the first floor is somewhat limited. I changed it a little bit:

/*
    @params permission 
    @return []
*/
// 
const REG_CODE = /^(.+)\.\d+$/; 
const handlePermission = permission => {
    // 
    permission = permission.map(item => Object.assign({}, item));

    // 
    permission.sort((a, b) => a[2] - b[2]);

    // 
    let parents = permission.reduce((data, item) => (data[item[2]] = item, data), {});

    // 
    let res = [];

    // 
    permission.forEach(item => {
        //code
        let parentCode = REG_CODE.exec(item[2]);

        // 
        if(!parentCode){
           res.push(item);
           return;
        }

        // children
        if(parentCode && parents[parentCode[1]]){
            parents[parentCode[1]].children = parents[parentCode[1]].children || [];
            parents[parentCode[1]].children.push(item);
        }
    });

    return res;
}

can be easily implemented with the set function under lodash .

const set = require('lodash/set');

[
    { 1: '20190805', 2: '1', 3: 'success' },
    { 1: '20191120', 2: '1.1', 3: 'success' },
    { 1: '20190212', 2: '1.1.1', 3: 'success' },
    { 1: '20190212', 2: '1.1.2', 3: 'success' },
    { 1: '20190212', 2: '1.1.3', 3: 'success' },
    { 1: '20190212', 2: '1.2', 3: 'success' },
    { 1: '20190212', 2: '1.2.1', 3: 'success' },
    { 1: '20190212', 2: '2', 3: 'success' },
    { 1: '20190212', 2: '2.1', 3: 'success' },
    { 1: '20190212', 2: '2.2.1', 3: 'success' },
    { 1: '20190212', 2: '2.2', 3: 'success' },
    { 1: '20190212', 2: '2.3', 3: 'success' },
    { 1: '20190212', 2: '2.3.1', 3: 'success' },
].reduce((f, l) => set(f, l['2'].split('.').map(item => item - 1).join('.children.'), l), []);

my method is stupid. Haha

function transData (datas,num) {
    num = num?num:1
    var res = [],sub = [];

    //
    datas.forEach(function (item) {
        var arr = item['2'].split('.');
        if (arr.length==num){
            res.push(item)
        }else{
            sub.push(item)
        }
    })

    //
    sub.forEach(function (item) {
        var key = item['2'].split('.').slice(0,num).join('.')
        res.forEach(function(itemIn){
            if (itemIn['2'] == key) {
                !itemIn.children&&(itemIn.children=[])
                itemIn.children.push(item)
            }
        })
    })

    //
    res.forEach(function (item) {
        if (item.children&&item.children.length>0){
            item.children = transData(item.children,num+1)
        }
    })
    
    return res;
}

var result = transData(obj);
console.log(result)

(in fact, it is not accurate to determine whether it is a parent by using String.prototype.slice and .length = 1 methods, but only to write ideas)

function fn(data, parentPath = null) {
  return data.filter(item => {
    if (parentPath === null && item[2].length === 1 || item[2].slice(0, -2) === parentPath) {
      item.children = fn(data, item[2])
      return true
    }
  })
}

expand (easy to read):

function fn(data, parentPath = null) {
  return data.filter(item => {
    if (parentPath === null && item[2].length === 1) {
      item.children = fn(data, item[2])
      return true
    }
    if(item[2].slice(0, -2) === parentPath) {
      item.children = fn(data, item[2])
      return true
    }
  })
}
Menu