简体   繁体   English

将平面对象数组转换为嵌套对象

[英]Transform flat array of objects into nested objects

I have an array of task objects and I want to transform these into a multidimensional object grouped by ownerID 我有一个任务对象数组,我想将它们转换为一个由ownerID分组的多维对象

var tasks = [   
{taskID: "1", title: "task1", ownerID: "100", ownerName: "John", allocation: 80},       
{taskID: "2", title: "task2", ownerID: "110", ownerName: "Sarah", allocation: 50}, 
{taskID: "3", title: "task3", ownerID: "110", ownerName: "Sarah", allocation: 50}, 
{taskID: "4", title: "task4", ownerID: "120", ownerName: "Mike", allocation: 25},
{taskID: "5", title: "task5", ownerID: "120", ownerName: "Mike", allocation: 45}];

This is my expected output: 这是我的预期输出:

var people = {

    100:    {   ownerName: "John", 
                tasks:  {       
                            {taskID: "1", title: "task1", allocation: 80}
                        }       
            },

    110:    {   ownerName: "Sarah", 
                tasks:  {       
                            {taskID: "2", title: "task2", allocation: 50}
                            {taskID: "3", title: "task3", allocation: 50}
                        }       
            },

    120:    {   ownerName: "Mike", 
                tasks:  {       
                            {taskID: "4", title: "task4", allocation: 25}
                            {taskID: "5", title: "task5", allocation: 45}
                        }       
            },


    };

I'm looping through the original data and assigning each row 我循环遍历原始数据并分配每一行

people[ownerID] = {};
person = people[ownerID];
person['ownerName'] = ownerName;
person['tasks'] = {};
person[taskID] = {};
task = person[taskId];
task['taskID'] = taskID;

This seems to group by ownerID fine and creates a nested object of tasks but it will only add one task for each person. 这似乎是由ownerID并创建一个嵌套的任务对象,但它只会为每个人添加一个任务。

Argh. 哎呀。 Any help really appreciated. 任何帮助真的很感激。

Here is a functional way to do it (assuming ownerName is functional dependent on ownerID ): 这是一种功能性的方法(假设ownerName的功能取决于ownerID ):

 const tasks = [ {taskID: "1", title: "task1", ownerID: "100", ownerName: "John", allocation: 80}, {taskID: "2", title: "task2", ownerID: "110", ownerName: "Sarah", allocation: 50}, {taskID: "3", title: "task3", ownerID: "110", ownerName: "Sarah", allocation: 50}, {taskID: "4", title: "task4", ownerID: "120", ownerName: "Mike", allocation: 25}, {taskID: "5", title: "task5", ownerID: "120", ownerName: "Mike", allocation: 45}]; const result = tasks.reduce( (acc, {taskID, title, ownerID, ownerName, allocation }) => { (acc[ownerID] = acc[ownerID] || { ownerName, tasks: [] }) .tasks.push( { taskID, title, allocation } ); return acc; }, {}); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

people[ownerID] = {};

person['tasks'] = {};

These lines don't check if an object with the same key exists before and create a new object each time. 这些行不会检查之前是否存在具有相同键的对象,并且每次都创建一个新对象。

Try changing it to 尝试将其更改为

people[ownerID] = people[ownerID] || {};

person['tasks'] = person['tasks'] || {};

Just one thing, the tasks should be an array, since objects can't hold another objects without having a key. 只有一件事,任务应该是一个数组,因为没有键,对象不能容纳另一个对象。

var tasks = [   
{taskID: "1", title: "task1", ownerID: "100", ownerName: "John", allocation: 80},       
{taskID: "2", title: "task2", ownerID: "110", ownerName: "Sarah", allocation: 50}, 
{taskID: "3", title: "task3", ownerID: "110", ownerName: "Sarah", allocation: 50}, 
{taskID: "4", title: "task4", ownerID: "120", ownerName: "Mike", allocation: 25},
{taskID: "5", title: "task5", ownerID: "120", ownerName: "Mike", allocation: 45}];

var transformed = tasks.reduce((obj, item)=> {
    if(!obj[item.ownerID]) {
        obj[item.ownerID] = {};
    }
    obj[item.ownerID].ownerName = item.ownerName;
    if(!obj[item.ownerID].tasks) {
        obj[item.ownerID].tasks = [];
    }
    obj[item.ownerID].tasks.push({taskID: item.taskID, title: item.title, allocation: item.allocation})
    return obj;
}, {})
console.log(transformed);

You could use the logical OR as default operator ans assign a new object if the peroperty does not exists. 如果peroperty不存在,您可以使用逻辑OR作为默认运算符并分配新对象。

 var tasks = [{ taskID: "1", title: "task1", ownerID: "100", ownerName: "John", allocation: 80 }, { taskID: "2", title: "task2", ownerID: "110", ownerName: "Sarah", allocation: 50 }, { taskID: "3", title: "task3", ownerID: "110", ownerName: "Sarah", allocation: 50 }, { taskID: "4", title: "task4", ownerID: "120", ownerName: "Mike", allocation: 25 }, { taskID: "5", title: "task5", ownerID: "120", ownerName: "Mike", allocation: 45 }], people = {}; tasks.forEach(({ taskID, title, ownerID, ownerName, allocation }) => { people[ownerID] = people[ownerID] || { ownerName, tasks: {} }; people[ownerID].tasks[taskID] = people[ownerID].tasks[taskID] || { taskID, title, allocation }; }); console.log(people); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM