简体   繁体   English

如何将对象的平面数组(可能有多个父对象)转换为嵌套的对象数组

[英]How to convert flat array of objects (with possibly multiple parents) into a nested array of objects

I have an array of tasks that are linked to one-another through parentId's.我有一系列通过 parentId 相互关联的任务。 However any task could have multiple parents.但是,任何任务都可以有多个父级。 Therefor not necessarily a simple single tree hierarchical structure.因此不一定是简单的单树层次结构。 What I would like to achieve is instead of parents[], I would like to have a children [].我想要实现的是,我想要一个孩子[],而不是父母[]。 However I cant seem to get my head around how to approach this recursively.然而,我似乎无法理解如何递归地处理这个问题。 Any help would be greatly appreciated.任何帮助将不胜感激。

Here is the Flat JSON array这是平面 JSON 数组

[
  {
    "_id": "4b04e450-06d5-4453-8d50-d3b2a70d9b2d",
    "task_name": "Parent2",
    "parents": []
  },
  {
    "_id": "a15ca08e-f13b-4d73-a496-ba23832ea233",
    "task_name": "Endpoints",
    "parents": [
      {
        "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
        "task_name": "Parent1"
      },
      {
        "_id": "4b04e450-06d5-4453-8d50-d3b2a70d9b2d",
        "task_name": "Parent2"
      }
    ]
  },
  {
    "_id": "ee78316a-491e-4db5-8f82-13b12b5b86fc",
    "task_name": "Mapping",
    "parents": [
      {
        "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
        "task_name": "Parent1"
      }
    ]
  },
  {
    "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
    "task_name": "Parent1",
    "parents": []
  }
]

What I would like to achieve is the following我想实现的是以下

[
  {
    "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
    "task_name": "Parent1",
    "children": [
      {
        "_id": "ee78316a-491e-4db5-8f82-13b12b5b86fc",
        "task_name": "Mapping",
        "children": []
      },
      {
        "_id": "a15ca08e-f13b-4d73-a496-ba23832ea233",
        "task_name": "Endpoints",
        "children": []
      }
    ]
  },
  {
    "_id": "4b04e450-06d5-4453-8d50-d3b2a70d9b2d",
    "task_name": "Parent2",
    "children": [
      {
        "_id": "a15ca08e-f13b-4d73-a496-ba23832ea233",
        "task_name": "Endpoints",
        "children": []
      }
    ]
  }
]

What I have tried我试过的

function transform(list, idAttr, parentAttr, childrenAttr) {
    if (!idAttr) idAttr = '_id';
    if (!parentAttr) parentAttr = 'parents';
    if (!childrenAttr) childrenAttr = 'children';

    var newArr = [];
    var lookup = {};
    list.forEach(function(obj) {
        lookup[obj[idAttr]] = obj;
        obj[childrenAttr] = [];
    });
    list.forEach(function(obj) {
        if (obj[parentAttr] != null) {
            lookup[obj[parentAttr]][childrenAttr].push(obj);
        } else {
            newArr.push(obj);
        }
    });
    return newArr;
};

This works fine if the parents key in the original array is equal to the _id of the task.如果原始数组中的父键等于任务的 _id,则此方法可以正常工作。 However I am not sure how to get this to work for a parent key that has an array of objects as a value.但是,我不确定如何使其适用于具有对象数组作为值的父键。

You could take an object with the _id as key and store the parents as well with their relation.您可以将一个带有_id的对象作为键,并将父对象与它们的关系一起存储。 At the end take the children of the items without parents.最后取没有父项的子项。

 var data = [{ _id: "4b04e450-06d5-4453-8d50-d3b2a70d9b2d", task_name: "Parent2", parents: [] }, { _id: "a15ca08e-f13b-4d73-a496-ba23832ea233", task_name: "Endpoints", parents: [{ _id: "97bbf892-8a2a-4f45-befd-4fdbebded04b", task_name: "Parent1" }, { _id: "4b04e450-06d5-4453-8d50-d3b2a70d9b2d", task_name: "Parent2" }] }, { _id: "ee78316a-491e-4db5-8f82-13b12b5b86fc", task_name: "Mapping", parents: [{ _id: "97bbf892-8a2a-4f45-befd-4fdbebded04b", task_name: "Parent1" }] }, { _id: "97bbf892-8a2a-4f45-befd-4fdbebded04b", task_name: "Parent1", parents: [] }], tree = function (data, root) { var t = {}; data.forEach(({ parents, ...o }) => { Object.assign(t[o._id] = t[o._id] || {}, o); if (!parents.length) { t[root] = t[root] || {}; t[root].children = t[root].children || []; t[root].children.push(t[o._id]); return; } parents.forEach(p => { Object.assign(t[p._id] = t[p._id] || {}, p); t[p._id].children = t[p._id].children || []; t[p._id].children.push(t[o._id]); }); }); return t[root].children; }(data); console.log(tree);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

You can keep the the flat JSON array structure and store only Id's for cross referencing like so (ids are just examples)您可以保留平面 JSON 数组结构并仅存储 Id 以便像这样交叉引用(ID 只是示例)

    [
        {
            "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
            "task_name": "Task1",
            "children": [
                "ee78316a-491e-4db5-8f82-13b12b5b86fc",
                "a15ca08e-f13b-4d73-a496-ba23832ea233"
            ],
            "parents": [
                "ee78316a-491e-4db5-8f82-13b12b5b86fc",
                "a15ca08e-f13b-4d73-a496-ba23832ea233"
            ]
        },
        {
            "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
            "task_name": "Task2",
            "children": [
                "ee78316a-491e-4db5-8f82-13b12b5b86fc",
                "a15ca08e-f13b-4d73-a496-ba23832ea233"
            ],
            "parents": [
                "ee78316a-491e-4db5-8f82-13b12b5b86fc",
                "a15ca08e-f13b-4d73-a496-ba23832ea233"
            ]
        },
        {
            "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
            "task_name": "Task3",
            "children": [
                "ee78316a-491e-4db5-8f82-13b12b5b86fc",
                "a15ca08e-f13b-4d73-a496-ba23832ea233"
            ],
            "parents": [
                "ee78316a-491e-4db5-8f82-13b12b5b86fc",
                "a15ca08e-f13b-4d73-a496-ba23832ea233"
            ]
        }
    ]

Or if you want to achieve it the way you currently desire you can use this function.或者,如果您想以您目前希望的方式实现它,您可以使用此功能。 Not completely tested but you get the point没有完全测试,但你明白了

var tasks =     [
  {
    "_id": "4b04e450-06d5-4453-8d50-d3b2a70d9b2d",
    "task_name": "Parent2",
    "parents": []
  },
  {
    "_id": "a15ca08e-f13b-4d73-a496-ba23832ea233",
    "task_name": "Endpoints",
    "parents": [
      {
        "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
        "task_name": "Parent1"
      },
      {
        "_id": "4b04e450-06d5-4453-8d50-d3b2a70d9b2d",
        "task_name": "Parent2"
      }
    ]
  },
  {
    "_id": "ee78316a-491e-4db5-8f82-13b12b5b86fc",
    "task_name": "Mapping",
    "parents": [
      {
        "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
        "task_name": "Parent1"
      }
    ]
  },
  {
    "_id": "97bbf892-8a2a-4f45-befd-4fdbebded04b",
    "task_name": "Parent1",
    "parents": []
  }
];

function transformTasks(tasks){
    var transformed = {};
    var transformedAsArray = [];
    for(var taskIndex in tasks){
        var task = tasks[taskIndex];
        if(transformed[task["_id"]] === undefined){
            transformed[task["_id"]] = {_id:task["_id"],task_name:task["task_name"],children:[]};
            transformedAsArray.push(transformed[task["_id"]]);
        }
        for(var parentIndex in task["parents"]){
            var parentTask = task["parents"][parentIndex];
            if(transformed[parentTask["_id"]] === undefined){
                transformed[parentTask["_id"]] = {_id:parentTask["_id"],task_name:parentTask["task_name"],children:[]};
                transformedAsArray.push(transformed[parentTask["_id"]]);
            }
            transformed[parentTask["_id"]].children.push(transformed[task["_id"]]);

        }
    }

    return transformedAsArray;
}

console.log(transformTasks(tasks));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将平面对象数组转换为嵌套对象数组 - Convert flat array of objects into nested array of objects "将平面对象数组转换为嵌套对象" - Convert an array of flat objects to nested objects 将平面对象数组转换为嵌套对象 - Convert array of flat objects to nested objects 将数组的平面数组转换为嵌套对象 - Convert flat array of array into nested objects JS - 洛达什; 嵌套对象(父/子)到平面阵列 - JS - Lodash; Nested Objects (parents/children) to flat array 将对象的隐蔽平面数组转换为嵌套对象数组 - Covert flat array of objects to array of nested objects 如何递归地将嵌套对象数组转换为平面对象数组? - How to recursively transform an array of nested objects into array of flat objects? 如何将对象数组转换为嵌套对象数组? - How to convert array of objects into nested array of objects? 如何将类别和子类别的平面数组转换为嵌套对象数组,其中每个子类别都嵌套在其父项中? - How to convert a flat array of categories and subcategories into an array of nested objects, where each subcategory is nested inside it's parent? 如何将包含子“路径”数组的平面数组转换为基于路径的嵌套对象数组? - How to convert flat array containing a child “path” array into a nested array of objects based on the path?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM