【问题标题】:Javascript build a tree from a string with object.create()Javascript 使用 object.create() 从字符串构建树
【发布时间】:2019-03-21 10:44:18
【问题描述】:

我想从一个字符串创建一个服务树,这些字符串是人的属性。 我设法做到了,但代码很丑陋,这对我来说是一个练习之王,因为我想使用“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": ""
        }]
    }]
}]

【问题讨论】:

  • 请添加您的尝试以及出了什么问题。顺便说一句 service !== serviceLevel 作为键。
  • The expected output would be 为什么?这是什么逻辑?
  • @JaromandaX :目标是制作一棵服务树……预期的输出看起来像一棵服务树。什么不合逻辑?
  • 你能拥有多个service: "EE" ...你能拥有多个根级服务吗,例如service: "FF"?如果是这样,例如拥有EE.EAFF.EA 是否有效?最后,你自己写过一行代码吗?
  • @NinaScholz 我的尝试没有让任何想法接近目标。问题是我真的不明白如何检查以这种方式创建的对象的存在。例如:让服务 = obj.service.split("."); for (让 i = 0; i

标签: javascript json object organizational-chart


【解决方案1】:

您可以在服务属性上使用split,然后使用forEach 循环和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)

【讨论】:

  • 该死!当然......最简单的事情往往是最好的!谢谢!
  • smthg 出了问题。有 2 个部门,其中一些孙子在每个部门都有相同的“名字”。所以二队的孙子们去了一队……我想我们应该拿另一个财产来建树。
【解决方案2】:

您可以获取一个虚拟对象并迭代服务级别。

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; }

【讨论】:

  • 谢谢。这是一种解决它的方法,即使我正在寻找使用“类”的方法。 :)
猜你喜欢
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多