2017-11-18 151 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)); 
相關問題