Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert 1D array sorted by ASCII order to a nested array in Javascript

Assume this below array of objects that sorted by code property in ascii order:

var codes = [
    { code: '01' },
    { code: '0101' },
    { code: '0102' },
    { code: '010201' },
    { code: '0103' },
    { code: '02' },
    { code: '0201' },
    { code: '0202' },
];

How can I convert this to a nested array like this :

var nestedCodes = [
    {
        code: '01',
        children: [
            { code: '0101' },
            {
                code: '0102',
                children: [
                    { code: '010201' }
                ]
            },
            { code: '0103' }
        ]
    },
    {
        code: '02',
        children: [
            { code: '0201' },
            { code: '0202' }
        ]
    }
];

The structure of codes is like concatenating multiple 0N that N can be a number between 1 and 9. Note that codes come from server and there would be some additional properties beside code like title but it doesn't matter in this problem.

The main idea here is to make an appropriate format for jsTree.

like image 484
AmirhosseinDZ Avatar asked Mar 05 '26 13:03

AmirhosseinDZ


1 Answers

You can do this with a recursive solution. The idea is to maintain the path (obtained as an array via String.prototype.match with a regex) and the parent under which you want to insert the code for each recursive call.

The parent keeps track of the node you want to pick in the "current" recursive call, and path helps in building the parent as you keep going deeper:

function insert(d, path, parent, arr) {
  if (path.length === 0) {
    arr.push(Object.assign({}, d));
    return;
  }
  var target = arr.find(e => e.code === parent);
  target.children = target.children || [];
  insert(d, path.slice(1), parent + path[0], target.children);
}

var codes = [
    { code: '01' },
    { code: '0101' },
    { code: '0102' },
    { code: '010201' },
    { code: '0103' },
    { code: '02' },
    { code: '0201' },
    { code: '0202' },
];

var res = codes.reduce((a, c) => {
  var p = c.code.match(/(0[1-9])/g);
  insert(c, p.slice(1), p[0], a);
  return a;
}, []);

console.log(res);

The assumption, of course, is that when a code is being inserted, its parent has already been inserted before.

like image 125
slider Avatar answered Mar 08 '26 04:03

slider



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!