如何创造多重深度'在JavaScript

时间:2018-06-18 10:09:53

标签: javascript arrays object recursion

我有一系列对象,我想知道如何将其格式化为一个选择框,使用连字符来表示每个级别更深。这是我的对象 -

let elements = {
  0: {
    id: 1,
    name: 'Parent folder',
    parent_id: null
  },
  1: {
    id: 2,
    name: 'Another parent folder',
    parent_id: null
  },
  2: {
    id: 3,
    name: 'Child folder 1',
    parent_id: 1
  },
  3: {
    id: 4,
    name: 'Child folder 2',
    parent_id: 1
  },
  4: {
    id: 5,
    name: 'Child of a child',
    parent_id: 4,
  },
}

我希望elements重新格式化,如下所示 -

let elements = {
  0: {
    id: 1,
    name: 'Parent folder',
    parent_id: null,
    depth: 0
  },
  1: {
    id: 3,
    name: 'Child folder 1',
    parent_id: 1,
    depth: 1
  },
  2: {
    id: 4,
    name: 'Child folder 2',
    parent_id: 1,
    depth: 1
  },
  3: {
    id: 5,
    name: 'Child of a child',
    parent_id: 4,
    depth: 2
  },
  4: {
    id: 2,
    name: 'Another parent folder',
    parent_id: null,
    depth: 0
  },
}

这样我就可以遍历对象,并根据深度变量 -

在以下结构中生成一个选择
Parent folder
- Child folder 1
- Child folder 2
-- Child of a child
Another parent folder

目前我正在通过一个进程循环我的对象并获得一个多级对象,所以也许我只需要弄清楚如何将它转换回一个深度的对象数组?

if(elements.length > 0) {
    for (let i = 0; i < elements.length; i++) {
        let obj = Object.assign({}, elements[i]);

        let depth = 0;
        obj.items = [];

        map[obj.id] = obj;

        let parent = obj.parent_id || '-';
        if (!map[parent]) {
            map[parent] = { items: [] }
        }
        map[parent].items.push(obj);
    }

    console.log(map);
    return map['-'].items;
}

我觉得有一个相对简单的答案,但我很挣扎!期待你的想法,谢谢!

1 个答案:

答案 0 :(得分:1)

您可以先创建一个树,以反映该关系,然后构建一个以后成为对象的平面数组。

&#13;
&#13;
function getTree(array) {
    var o = {};
    array.forEach(function ({ id, name, parent_id }) {
        Object.assign(o[id] = o[id] || {}, { id, name, parent_id });
        o[parent_id] = o[parent_id] || {};
        o[parent_id].children = o[parent_id].children || [];
        o[parent_id].children.push(o[id]);
    });
    return o.null.children;
}

function getFlat(array = [], level = 0) {
    return array.reduce((r, { id, name, parent_id, children }) =>
        r.concat({ id, name, parent_id, level }, getFlat(children, level + 1)), []);
}

var elements = { 0: { id: 1, name: 'Parent folder', parent_id: null }, 1: { id: 2, name: 'Another parent folder', parent_id: null }, 2: { id: 3, name: 'Child folder 1', parent_id: 1 }, 3: { id: 4, name: 'Child folder 2', parent_id: 1 }, 4: { id: 5, name: 'Child of a child', parent_id: 4 } },
    tree = getTree(Object.assign([], elements)),
    flat = getFlat(tree);

console.log(flat.map(({ name, level }) => '-'.repeat(level) + name).join('\n'));
console.log(Object.assign({}, flat));
console.log(tree);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;