【问题标题】:Create an tree of objects from arrays从数组创建对象树
【发布时间】:2019-04-15 21:04:53
【问题描述】:

我想从数组中创建一棵对象树。 在这里为我提供了一个很好的解决方案(我在这里发现了“减少”方法):Javascript build a tree from a string with object.create() 实际上,我的需求有点不同,我无法调整提供的代码......所以我回到这里寻求帮助! (谢谢)。 我将在本文末尾发布完整的初始代码

输入:

[
  {
    "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"
  }
]

输出:

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

初始代码:

function format(data) {
    const res = []
    data.forEach(obj => {
        obj.serviceTree.split('.').reduce((r, e, i, a) => {
            console.log(r, e, i, a);
            const oParent = r.find(({ name }) => name == a[i - 1]);
            const match = r.find(({ name }) => name == e);
            if (!match) {
                const o = Object.create(service);
                o.name = e;
                if (!a[i + 1]) {
                    o.serviceName = obj.serviceName;
                    o.serviceTree = obj.serviceTree;
                    o.serviceLevel = i;
                    o.serviceParent = (i == 0 ? 'root' : a[i - 1]);
                    o.people = [{
                        familyName: obj.familyName,
                        firstName: obj.firstName,
                        jobTitle: obj.jobTitle,
                        rank: obj.rank,
                        phone: obj.phone,
                        mobile: obj.mobile,
                        mail: obj.mail
                    }];

                    if (oParent) {
                        oParent.serviceChildren.push(o);
                    } else {
                        o.serviceChildren = [];
                        r.push(o);
                    }

                } else {
                    let treeStamp = a.slice();
                    treeStamp.pop();
                    o.serviceName = e;
                    o.serviceTree = treeStamp.join('.');
                    o.serviceLevel = i;
                    o.serviceParent = (i == 0 ? 'root' : a[i - 1]);
                    o.serviceChildren = [];
                    r.push(o);
                }
                return r;

            } else {
                if (!a[i + 1]) match.people.push({
                    familyName: obj.familyName,
                    firstName: obj.firstName,
                    jobTitle: obj.jobTitle,
                    rank: obj.rank,
                    phone: obj.phone,
                    mobile: obj.mobile,
                    mail: obj.mail
                });
                return match.serviceChildren;
            }
        }, res);
    });
    return res;
}

【问题讨论】:

  • 如果您无法调整答案,则答案可能有问题。
  • 是的,我已经对提供的代码进行了一些更改以使其正常工作...但实际上,这不是我最终要寻找的解决方案...

标签: javascript arrays object tree reduce


【解决方案1】:

您可以参与拆分服务并将其作为访问嵌套对象的关键。

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, { [i - 1]: serviceFather = 'root' }) => {
            o.serviceChildren = o.serviceChildren || {};
            o.serviceChildren[k] = o.serviceChildren[k] || { serviceFather, people: []  };
            return o.serviceChildren[k];
        }, { serviceChildren: result })
        .people.push({ name });
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我试图理解 '.reduce((o, k, i, { [i - 1]: serviceFather = 'root' })' :最后一个参数不是你的数组'正在工作?我无法想象你可以在这里填写参数......(?)
  • 正确的参数是通过数组解构,它获取实际索引之前的元素,如果没有可用的项目,则将'root'作为默认值。
  • 我明白了!它是 [i - 1] 或 serviceFather = 'root'
  • 大声笑,你拥有这个 ^^ 非常感谢。因为我不知道有可能我只是忘记了三元写作......再次感谢你所做的一切。如果我可能会问另一个问题:是否可以在调用该函数之前使用所有参数启动一个对象,并在调用该函数时将一个值推送到“serviceFather”参数?例如:让 myObj = {parameter1:“”,parameter2 :"",serviceFather:"root"...}, data=[...]; data.forEach(o,k,i, {[i - 1] : myObj.serviceParent = "root"} ?
  • 不可能在 destructuring assignment 取 plaxe 的地方分配一个值,但你可以进行更深层次的解构(这在我看来是行不通的)。也许评论部分不适合它。如有必要,您可以提出一个新问题。顺便说一句,conditional (ternary) operator ?: 不在上面的代码中。冒号: 是解构的一部分。
【解决方案2】:

给出的代码过于复杂。这可能很简单:

 const root = { name: "root", serviceChildren: {} };

 for(const { name, service } of input) {
    let acc = root;
    for(const key of service.split(".")) {
       if(!acc.serviceChildren[key]) {
         acc.serviceChildren[key] = {
           name: key,
           serviceFather: acc.name,
           serviceChildren: {},
           people: [],
        };
      }
     acc = acc.serviceChildren[key];
    }

    acc.people.push({ name });
 }

 const output = root.serviceChildren;

【讨论】:

  • 你绝对是对的......我非常努力地调整第一个代码,以至于我没有退后一步寻找另一个解决方案......谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 2020-10-25
  • 2020-06-08
  • 2018-05-15
  • 1970-01-01
相关资源
最近更新 更多