如何在Javascript中从数组创建树(父子)对象 [英] How to create a tree (parent-child) object from Array in Javascript

查看:27
本文介绍了如何在Javascript中从数组创建树(父子)对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似的数组

<预><代码>["parent1|child1|subChild1","parent1|child1|subChild2","父|子2|子子1","parent1|child2|subChild2","parent2|child1|subChild1","parent2|child1|subChild2","parent2|child2|subChild1",...]

其中 | 之前的第一个字符串是父字符串,而 | 之前的第二个字符串是父字符串.是孩子,第二个 | 之后的第三个字符串是子孩子

我怎样才能把这个数组转换成一个像

这样的对象<预><代码>[{"id": "parent1",孩子们":[{"id": "child1",孩子们":[{id":subChild1"}]}]}]

父 -> 子 -> 子子对象

根据塞巴斯蒂安的回答,我在下面尝试使用打字稿

私有 genTree(row) {让 self = this;如果(!行){返回;}const [parent, ...children] = row.split('|');if (!children || children.length === 0) {返回 [{身份证:父母,孩子们: []}];}返回 [{身份证:父母,孩子:self.genTree(children.join('|'))}];}私人合并深度(儿童){让 self = this;const res = children.reduce((result, curr) => {常量条目 = curr;const existing = result.find((e) => e.id === entry.id);如果(现有){existing.children = [].concat(existing.children, entry.children);} 别的 {结果.推(条目);}返回结果;}, []);for (让 i = 0; i < res.length; i++) {const 条目 = res[i];如果(entry.children && entry.children.length > 0){entry.children = self.mergeDeep(entry.children);}};返回资源;}私有构造树(statKeyNames){让 self = this;const res = this.mergeDeep(statKeyNames.map(self.genTree).map(([e]) => e));控制台日志(res);}

但这给了我:

<块引用>

无法读取未定义的属性 'genTree' 错误

更新:

根据塞巴斯蒂安的评论将 self.genTree 更改为 this.genTree.bind(this) 并且它没有任何问题地工作

解决方案

你必须为此使用递归.看看这里:

const arr = ["parent1|child1|subChild1","parent1|child1|subChild2","父|子2|子子1","parent1|child2|subChild2","parent2|child1|subChild1","parent2|child1|subChild2",parent2|child2|subChild1"];函数genTree(行){const [parent, ...children] = row.split('|');if (!children || children.length === 0) {返回 [{身份证:父母,孩子们: []}];}返回 [{身份证:父母,孩子:genTree(children.join('|'))}];};函数 mergeDeep(children) {const res = children.reduce((result, curr) => {常量条目 = curr;const existing = result.find((e) => e.id === entry.id);如果(现有){existing.children = [].concat(existing.children, entry.children);} 别的 {结果.推(条目);}返回结果;}, []);for (让 i = 0; i < res.length; i++) {const 条目 = res[i];如果(entry.children && entry.children.length > 0){entry.children = mergeDeep(entry.children);}};返回资源;}const res = mergeDeep(arr.map(genTree).map(([e]) => e));console.log(JSON.stringify(res, false, 2));

我在这里使用了两个助手:genTree(row) 递归地从每一行生成一个简单的树,以及 mergeDeep(children) 减少第一级树arr.map(genTree).map(([e]) => e) 的结果,然后遍历数组并递归地对所有 children条目的代码>.

I have an array like

[
  "parent1|child1|subChild1",
  "parent1|child1|subChild2",
  "parent|child2|subChild1",
  "parent1|child2|subChild2",
  "parent2|child1|subChild1",
  "parent2|child1|subChild2",
  "parent2|child2|subChild1",
.
.
.    
]

Wherein my first string before | is the parent and the second string before | is the child and the third string after the second | is the subchild

How can I convert this array into an object like

[
 {
  "id": "parent1",
  "children":[
   {
    "id": "child1",
    "children":[
     {
      "id": "subChild1"
     }
    ]
   }
  ]
 }
]

Parent -> child -> subchild object

Based on Sebastian's answer I tried below using typescript

private genTree(row) {
        let self = this;
        if (!row) {
            return;
        }
        const [parent, ...children] = row.split('|');
        if (!children || children.length === 0) {
            return [{
                id: parent,
                children: []
            }];
        }
        return [{
            id: parent,
            children: self.genTree(children.join('|'))
        }];
    }

    private mergeDeep(children) {
        let self = this;
        const res = children.reduce((result, curr) => {
            const entry = curr;
            const existing = result.find((e) => e.id === entry.id);
            if (existing) {
                existing.children = [].concat(existing.children, entry.children);
            } else {
                result.push(entry);
            }
            return result;
        }, []);
        for (let i = 0; i < res.length; i++) {
            const entry = res[i];
            if (entry.children && entry.children.length > 0) {
                entry.children = self.mergeDeep(entry.children);
            }
        };
        return res;
    }

private constructTree(statKeyNames){
    let self = this;
    const res = this.mergeDeep(statKeyNames.map(self.genTree).map(([e]) => e));
    console.log(res);
}

but this gives me:

Cannot read property 'genTree' of undefined" error

Update:

As per Sebastian's comment changed self.genTree to this.genTree.bind(this) and it worked without any issues

解决方案

You have to use recursion for that. Take a look here:

const arr = [
  "parent1|child1|subChild1",
  "parent1|child1|subChild2",
  "parent|child2|subChild1",
  "parent1|child2|subChild2",
  "parent2|child1|subChild1",
  "parent2|child1|subChild2",
  "parent2|child2|subChild1"
];

function genTree(row) {

  const [parent, ...children] = row.split('|');

  if (!children || children.length === 0) {
    return [{
      id: parent,
      children: []
    }];
  }

  return [{
    id: parent,
    children: genTree(children.join('|'))
  }];
};

function mergeDeep(children) {

  const res = children.reduce((result, curr) => {

    const entry = curr;

    const existing = result.find((e) => e.id === entry.id);
    if (existing) {

      existing.children = [].concat(existing.children, entry.children);
    } else {
      result.push(entry);
    }

    return result;
  }, []);

  for (let i = 0; i < res.length; i++) {

    const entry = res[i];
    if (entry.children && entry.children.length > 0) {
      entry.children = mergeDeep(entry.children);
    }
  };

  return res;
}

const res = mergeDeep(arr.map(genTree).map(([e]) => e));
console.log(JSON.stringify(res, false, 2));

I used two helpers here: genTree(row) which recursively generates a simple tree from each row, and mergeDeep(children) which reduces the first-level trees in the result of arr.map(genTree).map(([e]) => e), and then iterates over the array and recursively does the same thing to all children of each entry.

这篇关于如何在Javascript中从数组创建树(父子)对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆