Hierarchical Tree (Updated)

by Nalin Sajwan

JavaScript

console.time("Overall time");

class NestedDataUtility {

  constructor(textKey, textSeparator, parentSeparator) {
    this.textKey = textKey;
    this.textSeparator = textSeparator;
    this.parentSeparator = parentSeparator;
  };

  cloneJSON(obj) {
    try {
      return JSON.parse(JSON.stringify(obj));
    } catch(err) {
      return obj;
    }
  };

  textToNestedArr(dataArr) {
    return dataArr.map((v) => v.split(this.textSeparator));
  };
  
  addToHierarchy(val, level, hierarchy) {
    if (val[level]) {
      if (!hierarchy.hasOwnProperty(val[level])) {
        hierarchy[val[level]] = {};
      }
      this.addToHierarchy(val, level + 1, hierarchy[val[level]]);
    }
  };

  convertToNestedArr(item, parent) {
    const children = [];
    for (let k in item) {
      const obj = { [this.textKey]: k };
      if (typeof parent === "string" && parent.trim() !== "") {
        obj.parent = parent;
        parent = `${parent} ${this.parentSeparator} ${k}`;
      } else {
        obj.parent = null;
        parent = k;
      }
      
      const subData = this.convertToNestedArr(item[k], parent);
      
      if (obj.parent !== null) obj.parent = obj.parent;
      if (subData.length > 0) obj.children = subData;
      
      children.push(obj);
    }

    return children;
  };

  countLastChildren(arr) {
    if (arr.children) {
      let return_val = 0;
      arr.children.forEach((el) => return_val += this.countLastChildren(el));
      return return_val;
    } else {
      return 1;
    }
  };

  traverseTreeUpdateLength(tree) {
    for (let i = 0; i < tree.length; i++) {
      if (tree[i].children) {
        let sample = this.cloneJSON(tree[i]);
        tree[i].length = this.countLastChildren(sample);
      }
      if (Array.isArray(tree[i].children) && tree[i].children.length) {
        this.traverseTreeUpdateLength(tree[i].children);
      }
    }
  };
};

const nestedDataUtility = new NestedDataUtility('text', '/', '>');

const data = [
 ...