2017-11-18 155 views
2

我使用TypeScript作为Web应用程序的后端,我发现交集类型对于有效的SQL查询非常有用。基本上,如果我有以下表:如何按子对象对一组对象进行分组?

User 

userId: number 
userEmail: string 

Post 

postId: number 
userId: number (FK) 
postBody: string 

我可以与交叉点型(用户&邮政),看起来像这样结束了:

{ 
    userId: number; 
    userEmail: string; 
    postId: number; 
    postBody: string; 
} 

这意味着我可以使用这种类型来表示我从联合选择查询中返回的行。

问题是,我不得不拆开Web服务器中的数据。我必须编写迭代代码来为每个查询分组,这可以重复。这里是改造的,我试图让类型:

在:

[ 
    { 
    userId: 1, 
    userEmail: '[email protected]', 
    postId: 1, 
    postBody: 'User 1\'s first post', 
    }, 
    { 
    userId: 1, 
    userEmail: '[email protected]', 
    postId: 2, 
    postBody: 'User 1\'s second post', 
    }, 
    { 
    userId: 2, 
    userEmail: '[email protected]', 
    postId: 3, 
    postBody: 'User 2\'s first post', 
    }, 
] 

日期:

[ 
    { 
    userId: 1, 
    userEmail: '[email protected]', 
    posts: [ 
     { 
     postId: 1, 
     postBody: 'User 1\'s first post', 
     }, 
     { 
     postId: 2, 
     postBody: 'User 1\'s second post', 
     } 
    ], 
    }, 
    { 
    userId: 2, 
    userEmail: 'User 2\'s email', 
    posts: [ 
     { 
     postId: 3, 
     postBody: 'User 2\'s first post', 
     } 
    ] 
    } 
] 

我试图想出一个功能,我可以用它来做到这一点动态地,可能传入集合,父键名称的数组以及子集合的名称。我结束了与一个不成功的功能与以下签名:function group(coll: Array<any>, parentKeys: Array<string>, childCollName: string): Array<any>;

我想知道是否有人可以帮助我实现这一点。

到目前为止,我已经尝试过使用Lodash。但是,它的groupBy函数似乎不能说明子对象是否相等,并且在本例中它仍然给出了三个对象的数组。

回答

0

如何试图像下面,在循环会和创建对象

var arry = [ 
 
    { 
 
     userId: 1, 
 
     userEmail: '[email protected]', 
 
     postId: 1, 
 
     postBody: 'User 1\'s first post', 
 
    }, 
 
    { 
 
     userId: 1, 
 
     userEmail: '[email protected]', 
 
     postId: 2, 
 
     postBody: 'User 1\'s second post', 
 
    }, 
 
    { 
 
     userId: 2, 
 
     userEmail: '[email protected]', 
 
     postId: 3, 
 
     postBody: 'User 2\'s first post', 
 
    }, 
 
]; 
 

 
function createPost(obj) { 
 
    post = {}; 
 
    post.postId = obj.postId; 
 
    post.postBody = obj.postBody; 
 
    return post; 
 
} 
 
function convert(array) { 
 
    var map = {}; 
 
    for (var i = 0; i < array.length; i++) { 
 
     var currentObject = array[i]; 
 

 

 
     if (!map[currentObject.userId]) { 
 
      obj = {} 
 
      obj.userId = currentObject.userId; 
 
      obj.userEmail = currentObject.userEmail; 
 
      obj.posts = []; 
 

 
      map[obj.userId] = obj; 
 

 
     } 
 
     obj.posts.push(createPost(currentObject)); 
 
    } 
 
    var keys = Object.keys(map); 
 
    return keys.map(function (v) { return map[v]; }); 
 
} 
 
var r = convert(arry) 
 
console.log(r);

0

您可以使用Array.prototype.reduce()要达到的目标。

var source = 
 
    [ 
 
    { 
 
     userId: 1, 
 
     userEmail: '[email protected]', 
 
     postId: 1, 
 
     postBody: 'User 1\'s first post', 
 
    }, 
 
    { 
 
     userId: 1, 
 
     userEmail: '[email protected]', 
 
     postId: 2, 
 
     postBody: 'User 1\'s second post', 
 
    }, 
 
    { 
 
     userId: 2, 
 
     userEmail: '[email protected]', 
 
     postId: 3, 
 
     postBody: 'User 2\'s first post', 
 
    }, 
 

 

 
] 
 

 

 
var grouped = source.reduce(function(v,k){ 
 
    if (!v[k.userId]) { 
 
     v[k.userId]={}; 
 
    } 
 
    var group = v[k.userId]; 
 
    group.userId=k.userId; 
 
    group.userEmail=k.userEmail; 
 
    if(!group.posts){ 
 
     group.posts=[]; 
 
    } 
 
    group.posts.push({postId: k.postId, 
 
     postBody:k.postBody}) 
 
    return v; 
 
},{}) 
 

 
var dataArray = []; 
 
for(var o in grouped) { 
 
    if (grouped.hasOwnProperty(o)) { 
 
     dataArray.push(grouped[o]); 
 
    } 
 
} 
 

 
console.log(JSON.stringify(dataArray,null, 2));

0

这里的另取与减少,一些和解构

DEMO

const grouped = [ 
    { 
    userId: 1, 
    userEmail: '[email protected]', 
    postId: 1, 
    postBody: 'User 1\'s first post', 
    }, 
    { 
    userId: 1, 
    userEmail: '[email protected]', 
    postId: 2, 
    postBody: 'User 1\'s second post', 
    }, 
    { 
    userId: 2, 
    userEmail: '[email protected]', 
    postId: 3, 
    postBody: 'User 2\'s first post', 
    } 
]; 

const sorted = grouped.reduce((acc, nxt) => { 
    const { userId, userEmail, ...rest } = nxt; 
    let index; 
    let user; 

    const accHasUser = acc.some((obj, i) => { 
     if (obj && obj.userId === userId) { 
      index = i; 
      return true; 
     } 
     return false; 
    }); 

    if (!accHasUser) { 
     user = { userId, userEmail, posts: [rest] }; 
     acc.push(user); 
    } else { 
     acc[index].posts.push(rest); 
    } 

    return acc; 
}, []); 

console.log(JSON.stringify(sorted)); 
相关问题