我有一个数组(作为mongoDB查询的输出) 根据字段“数字”'
进行排序results = [{
user: u1,
number: 1,
msg: m1
}, {
user: u2,
number: 2,
msg: m2
}, {
user: u3,
number: 3,
msg: m3
}, {
user: u2,
number: 4,
msg: m4
}, {
user: u1,
number: 5,
msg: m5
}]
我想将此数组转换为二维数组,如下所示。请注意,嵌套数组是根据'数字排序的。字段
newResults = [{
user: u1,
msg: [{nmsg: m1, number: 1}, {nmsg: m5, number: 5}]
}, {
user: u2,
msg: [{nmsg: m2, number: 2 }, {nmsg: m4, number: 4}]
}, {
user: u3,
msg: [{nmsg: m3, number 3}]
}
}]
我可以通过2个for循环来实现这一点,但是,2个循环似乎效率低下,因为数组可以增长到非常大的大小。
有没有办法,可能是使用库还是直接从mongoDB中获得相同的结果?
此外,Mongodb的结构非常简单
作为
{
user
number
msg
}
谢谢
答案 0 :(得分:0)
你可以使用mongodb aggregation来做到这一点。您需要按编号(使用$sort)按用户进行排序,并生成按键共享同一组的数据数组(使用$group和$push)。
db.collection.aggregate([
{ $sort: {number: 1}},
{$group: {
_id: "$user",
msg: {$push: {nmsg: "$msg", number: "$number" }}
}}
])
为您的数据获得了这样的结果:
{
"_id" : "u1",
"msg" : [
{
"nmsg" : "m1",
"number" : 1
},
{
"nmsg" : "m5",
"number" : 5
}
]
}
{
"_id" : "u2",
"msg" : [
{
"nmsg" : "m2",
"number" : 2
},
{
"nmsg" : "m4",
"number" : 4
}
]
}
{ "_id" : "u3", "msg" : [ { "nmsg" : "m3", "number" : 3 } ] }
答案 1 :(得分:0)
您可以使用lodash缩减和订购结果。我在下面的示例中使用了_.chain()
,因为它使代码更具可读性,并且可以提高效率。
var results = [
{ user: 'u1', number: 1, msg: 'm1' },
{ user: 'u2', number: 2, msg: 'm2' },
{ user: 'u3', number: 3, msg: 'm3' },
{ user: 'u2', number: 4, msg: 'm4' },
{ user: 'u1', number: 5, msg: 'm5' }
];
var reduced = _.chain(results)
.groupBy('user').toArray().map(function(record) {
return {
user : _.chain(record).head().get('user'),
msg : _.chain(record).map(function(data) {
return { nmsg: data.msg, number: data.number };
}).sortBy('number')
}
}).sortBy('user').value();
var types = [
{ name : 'str', pattern : /("(?:\\.|[^"\\])*")/g },
{ name : 'num', pattern : /(\b[-+]?[0-9]*\.?[0-9]+\b)/g }
]
document.querySelector('code.javascript').innerHTML = types.reduce(function(code, type) {
return code.replace(type.pattern, '<span class="' + type.name + '">$1</span>')
}, JSON.stringify(reduced, null, ' '))
code.javascript {
font-family: Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,sans-serif;
font-size: 12px;
white-space: pre;
}
code.javascript .str { color: #007F00; }
code.javascript .num { color: #7F007F; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.0.0/lodash.min.js"></script>
<code class="javascript"></code>