2017-11-18 7 views
2

私はWebアプリケーションのバックエンドにTypeScriptを使用しています。効率的な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]', 
    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', 
     } 
    ] 
    } 
] 

で:

[ 
    { 
    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 group(coll: Array<any>, parentKeys: Array<string>, childCollName: string): Array<any>;

誰かがこれを実装するのを手伝ってくれるのだろうかと思っていた。

これまでのところ、私はすでにLodashを使ってみました。しかし、そのgroupBy関数は、サブオブジェクトが等しいことを伝えることができないようで、この例では3つのオブジェクトの配列を返します。

答えて

0

どのようにループに行くと、オブジェクトに

あなたは目標を達成するために Array.prototype.reduce()を使用することができます

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

を作成し、以下のような何かをしようとしてについて。

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)); 
を構造化代入、と取る減らしています
関連する問題