下划线对嵌套数组进行分组和排序
Underscore group and sort nested arrays
使用 meteor,我有一个 mongo 聚合返回一个反应性变量,如下所示:
[{
"_id": "game1",
"playerpicks": [
{
"player": "Chris",
"pick": "atsa"
},
{
"player": "al",
"pick": "suh"
},
{
"player": "al",
"pick": "atsh"
},
{
"player": "Chris",
"pick": "sua"
}] },{
"_id": "game2",
"playerpicks": [
{
"player": "al",
"pick": "atsa"
},
{
"player": "Chris",
"pick": "suh"
},
{
"player": "Chris",
"pick": "atsh"
},
{
"player": "al",
"pick": "sua"
}] }, .... ]
我需要将这些数据转换成理想情况下如下所示的网格:
GAME al Chris
game1 suh/atsh sua/atsa
game2 sua/atsa suh/atsh
假设这是一个太大的挑战,我可以做这样的事情:
game 1 al: suh/atsh Chris: sua/atsa
game 2 al: sua/atsa Chris: suh/atsh
我看到 Mongo 需要在客户端进行排序,所以我专注于使用下划线,但即使在 _.sortBy 或 _.groupBy 嵌套数组 "playerpicks"
我试过如下:
_.each(monArr, function(obj){ _.each(obj.playerpicks, function(nst){ _.groupBy( nst.player ) }) })
以及:
_.groupBy(monArr, function(obj){return obj.playerpicks.player})
但我还差得远呢。没有数据返回。非常感谢任何建议
这是一个使用无数下划线函数的解决方案,分解成离散的块,希望能使其更具可读性:
// helper function to combine a player's picks into a string delimited by '/'
let combinePicks = player => _.pluck(player, 'pick').join('/');
// helper function to group a game by a player
let groupGame = game => _.chain(game.playerpicks)
.groupBy('player')
.mapObject(combinePicks)
.value();
// map the data to create the object in the required form
let result = _.map(data, game => _.extend({GAME: game._id}, groupGame(game) ));
对于不支持 mapObject
(1.8 之前)的早期版本的下划线,可以使用 reduce:
实现相同的结果
let combinePicks = function(memo, player, key){
memo[key] = _.pluck(player, 'pick').join('/');
return memo;
}
let groupGame = game => _.chain(game.playerpicks)
.groupBy('player')
.reduce(combinePicks, {})
.value();
var data = [{
"_id": "game1",
"playerpicks": [
{
"player": "Chris",
"pick": "atsa"
},
{
"player": "al",
"pick": "suh"
},
{
"player": "al",
"pick": "atsh"
},
{
"player": "Chris",
"pick": "sua"
}] },{
"_id": "game2",
"playerpicks": [
{
"player": "al",
"pick": "atsa"
},
{
"player": "Chris",
"pick": "suh"
},
{
"player": "Chris",
"pick": "atsh"
},
{
"player": "al",
"pick": "sua"
}] }
];
let combinePicks = player => _.pluck(player, 'pick').join('/');
let groupGame = game => _.chain(game.playerpicks)
.groupBy('player')
.mapObject(combinePicks)
.value();
let result = _.map(data, game => _.extend({GAME: game._id}, groupGame(game) ));
document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<p>
<pre id="result"></pre>
</p>
使用 meteor,我有一个 mongo 聚合返回一个反应性变量,如下所示:
[{
"_id": "game1",
"playerpicks": [
{
"player": "Chris",
"pick": "atsa"
},
{
"player": "al",
"pick": "suh"
},
{
"player": "al",
"pick": "atsh"
},
{
"player": "Chris",
"pick": "sua"
}] },{
"_id": "game2",
"playerpicks": [
{
"player": "al",
"pick": "atsa"
},
{
"player": "Chris",
"pick": "suh"
},
{
"player": "Chris",
"pick": "atsh"
},
{
"player": "al",
"pick": "sua"
}] }, .... ]
我需要将这些数据转换成理想情况下如下所示的网格:
GAME al Chris
game1 suh/atsh sua/atsa
game2 sua/atsa suh/atsh
假设这是一个太大的挑战,我可以做这样的事情:
game 1 al: suh/atsh Chris: sua/atsa
game 2 al: sua/atsa Chris: suh/atsh
我看到 Mongo 需要在客户端进行排序,所以我专注于使用下划线,但即使在 _.sortBy 或 _.groupBy 嵌套数组 "playerpicks"
我试过如下:
_.each(monArr, function(obj){ _.each(obj.playerpicks, function(nst){ _.groupBy( nst.player ) }) })
以及:
_.groupBy(monArr, function(obj){return obj.playerpicks.player})
但我还差得远呢。没有数据返回。非常感谢任何建议
这是一个使用无数下划线函数的解决方案,分解成离散的块,希望能使其更具可读性:
// helper function to combine a player's picks into a string delimited by '/'
let combinePicks = player => _.pluck(player, 'pick').join('/');
// helper function to group a game by a player
let groupGame = game => _.chain(game.playerpicks)
.groupBy('player')
.mapObject(combinePicks)
.value();
// map the data to create the object in the required form
let result = _.map(data, game => _.extend({GAME: game._id}, groupGame(game) ));
对于不支持 mapObject
(1.8 之前)的早期版本的下划线,可以使用 reduce:
let combinePicks = function(memo, player, key){
memo[key] = _.pluck(player, 'pick').join('/');
return memo;
}
let groupGame = game => _.chain(game.playerpicks)
.groupBy('player')
.reduce(combinePicks, {})
.value();
var data = [{
"_id": "game1",
"playerpicks": [
{
"player": "Chris",
"pick": "atsa"
},
{
"player": "al",
"pick": "suh"
},
{
"player": "al",
"pick": "atsh"
},
{
"player": "Chris",
"pick": "sua"
}] },{
"_id": "game2",
"playerpicks": [
{
"player": "al",
"pick": "atsa"
},
{
"player": "Chris",
"pick": "suh"
},
{
"player": "Chris",
"pick": "atsh"
},
{
"player": "al",
"pick": "sua"
}] }
];
let combinePicks = player => _.pluck(player, 'pick').join('/');
let groupGame = game => _.chain(game.playerpicks)
.groupBy('player')
.mapObject(combinePicks)
.value();
let result = _.map(data, game => _.extend({GAME: game._id}, groupGame(game) ));
document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<p>
<pre id="result"></pre>
</p>