Javascript построить дерево из строки с помощью object.create () - PullRequest
0 голосов
/ 21 марта 2019

Я бы хотел создать дерево сервисов из строки, являющейся собственностью людей. Мне удается это сделать, но код довольно уродлив, и для меня это король практики, потому что я хотел бы сделать это с помощью «класса» объектов, используя «Object.create ()», где класс выглядеть так:

let service = {
        serviceFather: "",
        serviceChildren: [],
        people: [],
        }
    }; 

Пример ввода:

[
  {
    "name": "John Doe",
    "service": "EE",
  },
  {
    "name": "Jane Doe",
    "service": "EE.EA",
  },
  {
    "name": "Jack Smith",
    "service": "EE.EA.EB",
  },
  {
    "name": "Jill Smith",
    "service": "EE.EA.EC"
  },
  {
    "name": "Jake Smith",
    "serviceLevel": "EE.EA.EC"
  }
]

Ожидаемый результат будет:

[
{
    "name": "EE",
    "serviceFather": "root",
    "people": [
    {
        "name": "John Doe"
    }],
    "serviceChildren": [
    {
        "name": "EA",
        "serviceFather": "EE",
        "people": [
        {
            "name": "Jane Doe"
        }],
        "serviceChildren": [
        {
            "name": "EB",
            "serviceFather": "EA",
            "people": [
            {
                "name": "Jack Smith"
            }],
            "sousService": ""
        },
        {
            "name": "EC",
            "serviceFather": "EA",
            "people": [
            {
                "name": "Jill Smith"
            },
            {
                "name": "Jake Smith"
            }],
            "sousService": ""
        }]
    }]
}]

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Вы можете взять фиктивный объект и повторить уровни обслуживания.

var data = [{ name: "John Doe", service: "EE" }, { name: "Jane Doe", service: "EE.EA" }, { name: "Jack Smith", service: "EE.EA.EB" }, { name: "Jill Smith", service: "EE.EA.EC" }, { name: "Jake Smith", service: "EE.EA.EC" }],
    result = [];

data.forEach(({ name, service }) => {
    service
        .split('.')
        .reduce((o, k, i, a) => {
            var temp = (o.serviceChildren = o.serviceChildren || []).find(({ name }) => name === k);
            if (!temp) {
                o.serviceChildren.push(temp = {
                    name: k,
                    serviceFather: a[i - 1] || 'root',
                    people: []
                });
            }
            return temp;
        }, { serviceChildren: result })
        .people.push({ name });
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 21 марта 2019

Вы можете использовать split для свойства службы, а затем forEach loop и reduce для итерации вложенного дерева и добавления в массив.

const data = [{ "name": "John Doe", "service": "EE" }, { "name": "Jane Doe", "service": "EE.EA" }, { "name": "Jack Smith", "service": "EE.EA.EB" },
  { "name": "Jill Smith", "service": "EE.EA.EC" }, { "name": "Jake Smith", "service": "EE.EA.EC" }
]

let service = {
  serviceFather: "",
  serviceChildren: [],
  people: [],
};

function create(data) {
  const res = []
  data.forEach(obj => {
    obj.service.split('.').reduce((r, e, i, a) => {
      const match = r.find(({ name }) => name == e);
      if(!match) {
        const o = Object.create(service);
        o.name = e;
        o.serviceFather = (i == 0 ? 'root' : a[i - 1])
        o.people = [{ name: obj.name }]
        o.serviceChildren = [];
        r.push(o)
        return r;
      } else {
        if(!a[i + 1]) match.people.push({ name: obj.name })
        return match.serviceChildren
      }
    }, res)
  })
  return res;
}

const result = create(data)
console.log(result)
...