Помогите разобраться паттерн Composite JavaScript дерево сотрудников

Задача построить дерево сотрудников из Manager и Dev, у менеджеров в подчинении тоже есть менеджеры которым подчиняются разработчики.

Исходные данные, массив объектов сотрудников.

[{
    "id": 1,
    "rm_id": null,
    "name": "Max",
    "salary": 1415
  },
  {
    "id": 2,
    "rm_id": 1,
    "name": "Bob",
    "salary": 1248
  },
  {
    "id": 3,
    "rm_id": 1,
    "name": "Sten",
    "salary": 679
  },
  {
    "id": 4,
    "rm_id": 2,
    "name": "Gill",
    "salary": 1484
  },
  {
    "id": 5,
    "rm_id": 2,
    "name": "Masedon",
    "salary": 583
  },
  {
    "id": 6,
    "rm_id": 2,
    "name": "Ellissa",
    "salary": 1289
  }]

rm_id это - идентификатор родителя.

Почитав об Composite я написала такой код.

class Emploee {
  constructor(obj) {
    this.id = obj.id;
    this.rm_id = onj.rm_id;
    this.name = obj.name;
    this.salary = obj.salary;
  }
}

class Manager extends Emploee {
  constructor(obj) {
    super(obj);
    if (this.rm_id !== null) {
      this.parent = []
    }
    this.children = []
  }
  setParent(obj) {
    if (this.parent) {
      this.parent.push(obj)
    }
  }
  setChildren(obj) {
    this.children.push(obj)
  }
}

class Dev extends Emploee {
  constructor(obj) {
    super(obj);
    this.parent = [];
  }
  setParent(obj) {
    if (this.parent) {
      this.parent.push(obj)
    }
  }
}

Проблема в том, что я не понимаю как теперь создать сотрудников, и само дерево.

Я думала создать функцию которая пробежкой по массиву исходных объектов будет создавать new Manager или new Dev. Но в таком случае я не понимаю, мне для всех объектов нужны переменные? Или как потом к ним обращаться?

Пожалуйста, помогите разобраться как реализовать дерево сотрудников с помощью Composite. Ожидаемая структура структура дерева


Ответы (1 шт):

Автор решения: Aziz Umarov

Если чуток почитать повнимательнее, то можно получить такой результат

class Emploee {
  constructor(obj) {
    this.id = obj.id;
    this.manager_id = obj.rm_id;
    this.name = obj.name;
    this.salary = obj.salary;
    this.emploees = [];
  }
  
  setManager(obj) {
    if (this.manager_id) {
      this.manager_id = obj.id
    }
  }
  addEmploee(obj) {
    obj.setManager(this);
    this.emploees.push(obj);
  }
  
  removeEmploee(obj) {
    this.emploees = this.emploees.filter(emploee => emploee.id != obj.id);
  }
}



let emploeeDraft = [{
    "id": 1,
    "rm_id": null,
    "name": "Max",
    "salary": 1415
  },
  {
    "id": 2,
    "rm_id": 1,
    "name": "Bob",
    "salary": 1248
  },
  {
    "id": 3,
    "rm_id": 1,
    "name": "Sten",
    "salary": 679
  },
  {
    "id": 4,
    "rm_id": 2,
    "name": "Gill",
    "salary": 1484
  },
  {
    "id": 5,
    "rm_id": 2,
    "name": "Masedon",
    "salary": 583
  },
  {
    "id": 6,
    "rm_id": 2,
    "name": "Ellissa",
    "salary": 1289
  }];
  
 let result = emploeeDraft.map(emploee => new Emploee(emploee)).map((emploee, index, arr) => (arr.filter(i=> i.id == emploee.manager_id)[0]?.addEmploee(emploee), emploee));
 
 console.log(result);

или как пример частично так

class Emploee {
  constructor(obj) {
    this.id = obj.id;
    this.manager_id = obj.rm_id;
    this.name = obj.name;
    this.salary = obj.salary;
    this.emploees = [];
  }
  
  setManager(obj) {
    if (this.manager_id) {
      this.manager_id = obj.id
    }
  }
  addEmploee(obj) {
    obj.setManager(this);
    this.emploees.push(obj);
  }
  
  removeEmploee(obj) {
    this.emploees = this.emploees.filter(emploee => emploee.id != obj.id);
  }
}



let emploeeDraft = [{
    "id": 1,
    "rm_id": null,
    "name": "Max",
    "salary": 1415
  },
  {
    "id": 2,
    "rm_id": 1,
    "name": "Bob",
    "salary": 1248
  },
  {
    "id": 3,
    "rm_id": 1,
    "name": "Sten",
    "salary": 679
  },
  {
    "id": 4,
    "rm_id": 2,
    "name": "Gill",
    "salary": 1484
  },
  {
    "id": 5,
    "rm_id": 2,
    "name": "Masedon",
    "salary": 583
  },
  {
    "id": 6,
    "rm_id": 2,
    "name": "Ellissa",
    "salary": 1289
  }];
  
 let result = emploeeDraft.map(emploee => new Emploee(emploee)).map((emploee, index, arr) => (arr.filter(i=> i.id == emploee.manager_id)[0]?.addEmploee(emploee), emploee))[0];
 
 console.log(result);

→ Ссылка