如何使用哈希图或数组映射到 return 总数最高的类别?
How can I use a hashmap or map of an array to return the category with the highest total?
这是我的数组。
donations = [
{
donateTo: "BaseCamp",
amount: 1000,
date: "12/19/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 3000,
date: "12/12/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 2000,
date: "12/11/2014, 08:40"
}
];
我怎样才能 return 这样的事情?其中 donateTo
的捐赠总额最高的捐赠 return 与该总数以及构成该总数的礼物数量一起计算。
{ donateTo: "Where Most Needed", total: 5000, count: 2}
我以前能够使用 MongoDB 获得结果,但是因为我使用的是 Meteor,聚合真的很难看而且没有反应。我宁愿获取光标,然后在客户端使用 javascript 函数来获取我需要的数据。
谢谢
您可以遍历项目并将它们分组到一个对象中,然后遍历对象中的属性以找到最大的数量:
var donations = [
{
donateTo: "BaseCamp",
amount: 1000,
date: "12/19/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 3000,
date: "12/12/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 2000,
date: "12/11/2014, 08:40"
}
];
var sums = {};
for (var i = 0; i < donations.length; i++) {
var donateTo = donations[i].donateTo;
if (sums.hasOwnProperty(donateTo)) {
sums[donateTo].amount += donations[i].amount;
sums[donateTo].count++;
} else {
sums[donateTo] = { donateTo: donateTo, amount: donations[i].amount, count: 1 };
}
}
var obj = null;
for (donateTo in sums) {
if (obj == null || sums[donateTo].amount > obj.amount) {
obj = sums[donateTo];
}
}
// show in Whosebug snippet
document.write(JSON.stringify(obj));
您可以先迭代文档以按 donateTo
字段将它们分组。
var m = {}; // to hold the grouped records by `donateTo`
donations.forEach(function(i){
if(!m[i["donateTo"]]){
m[i["donateTo"]] = {};
m[i["donateTo"]] = i;
m[i["donateTo"]]["count"] = 1;
}
else{
m[i["donateTo"]]["count"]++;
m[i["donateTo"]]["amount"] += i.amount;
}
});
然后找到数量最多的组:
var result = {amount:0}; // to hold the group with the largest amount
Object.keys(m).forEach(function(key){
if(m[key].amount > result.amount){
result = m[key];
}
})
delete result["date"];
console.log(result);
没有超级巧妙的方法可以做到这一点,因为您必须累加所有总数,然后在最后选择最高的,而数组中的最后一项可能会完全改变最高值,因此您必须累加所有的小计,你去。
下面的这个函数累积遇到的所有 donateTo
字符串的映射,并为每个字符串保留 运行 总数和 cnt。随着它的进行,它会跟踪到目前为止哪个 donateTo
键的总数最高,从而节省额外的传递来计算最高的。
function findHighestSum(list) {
// collect cumulative totals
var totals = {}, highestTotal = 0, highestKey;
list.forEach(function(item) {
var key = item.donateTo;
if (!totals[key]) {
totals[key] = {amount: item.amount, cnt: 1};
} else {
totals[key].amount += item.amount;
totals[key].cnt++;
}
if (totals[key].amount > highestTotal) {
highestTotal = totals[key].amount;
highestKey = key;
}
});
// { donateTo: "Where Most Needed", total: 5000, count: 2}
return {donateTo: highestKey, total: highestTotal, count: totals[highestKey].cnt};
}
下面是一个使用下划线的实现:
var orgs = {};
_.each(donations, function(donation) {
if (orgs[donation.donateTo] == null)
orgs[donation.donateTo] = 0;
orgs[donation.donateTo] += donation.amount;
});
var amount = _.max(_.values(orgs));
var donateTo = _.invert(orgs)[amount];
var count = _.where(donations, {donateTo: donateTo}).length;
var result = {donateTo: donateTo, amount: amount, count: count};
console.log(result);
因为下划线很有趣!
_.chain(donations)
.reduce(function(m, c) {
var findItem = _.findWhere(m, { 'donateTo': c.donateTo});
if (findItem) {
findItem.count++;
findItem.total += c.amount;
} else {
m.push({
'donateTo':c.donateTo,
'count':1,
'total':c.amount});
};
return m; }, [])
.max(function(k) { return k.total})
.value();
使用下划线...
// reduce donations, finally returning object with largest amount total
var highest = _.reduce(donations, function(memo, item, index){
// add to amount total if group exists, else init group
if(memo[item.donateTo]){
memo[item.donateTo].amount += item.amount;
memo[item.donateTo].count++;
} else {
memo[item.donateTo] = {
donateTo: item.donateTo,
amount:item.amount,
count:1
};
}
// if it is last iteration...
if(index === donations.length - 1){
// extract the max value
memo = _.max(_.toArray(memo), function(item){
return item.amount;
});
}
return memo;
}, {});
使用下划线 js ...
// return the max (amount) of sorted, and collapsed array
var result = _.max( _.reduce( _.sortBy(donations, 'donateTo'), function(memo, item){
// if the last item has same key, update it (items are sorted by `donateTo`)
var _last = _.last(memo);
if(_last && _last.donateTo === item.donateTo){
_last.amount += item.amount;
_last.count++;
// otherwise create it
} else {
memo.push( _.extend( _.omit(item, 'date'), {'count':1} ) );
}
return memo
}, []), 'amount');
下划线高尔夫...
var h = {}, c={};
var result = _.max(donations, function(o){ var i = o.donateTo;
delete o.date; c[i] = ++c[i]||1; o.count=c[i];
return o.amount = h[i] = (h[i]||0)+o.amount
});
这是我的数组。
donations = [
{
donateTo: "BaseCamp",
amount: 1000,
date: "12/19/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 3000,
date: "12/12/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 2000,
date: "12/11/2014, 08:40"
}
];
我怎样才能 return 这样的事情?其中 donateTo
的捐赠总额最高的捐赠 return 与该总数以及构成该总数的礼物数量一起计算。
{ donateTo: "Where Most Needed", total: 5000, count: 2}
我以前能够使用 MongoDB 获得结果,但是因为我使用的是 Meteor,聚合真的很难看而且没有反应。我宁愿获取光标,然后在客户端使用 javascript 函数来获取我需要的数据。
谢谢
您可以遍历项目并将它们分组到一个对象中,然后遍历对象中的属性以找到最大的数量:
var donations = [
{
donateTo: "BaseCamp",
amount: 1000,
date: "12/19/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 3000,
date: "12/12/2014, 08:40"
},
{
donateTo: "Where Most Needed",
amount: 2000,
date: "12/11/2014, 08:40"
}
];
var sums = {};
for (var i = 0; i < donations.length; i++) {
var donateTo = donations[i].donateTo;
if (sums.hasOwnProperty(donateTo)) {
sums[donateTo].amount += donations[i].amount;
sums[donateTo].count++;
} else {
sums[donateTo] = { donateTo: donateTo, amount: donations[i].amount, count: 1 };
}
}
var obj = null;
for (donateTo in sums) {
if (obj == null || sums[donateTo].amount > obj.amount) {
obj = sums[donateTo];
}
}
// show in Whosebug snippet
document.write(JSON.stringify(obj));
您可以先迭代文档以按 donateTo
字段将它们分组。
var m = {}; // to hold the grouped records by `donateTo`
donations.forEach(function(i){
if(!m[i["donateTo"]]){
m[i["donateTo"]] = {};
m[i["donateTo"]] = i;
m[i["donateTo"]]["count"] = 1;
}
else{
m[i["donateTo"]]["count"]++;
m[i["donateTo"]]["amount"] += i.amount;
}
});
然后找到数量最多的组:
var result = {amount:0}; // to hold the group with the largest amount
Object.keys(m).forEach(function(key){
if(m[key].amount > result.amount){
result = m[key];
}
})
delete result["date"];
console.log(result);
没有超级巧妙的方法可以做到这一点,因为您必须累加所有总数,然后在最后选择最高的,而数组中的最后一项可能会完全改变最高值,因此您必须累加所有的小计,你去。
下面的这个函数累积遇到的所有 donateTo
字符串的映射,并为每个字符串保留 运行 总数和 cnt。随着它的进行,它会跟踪到目前为止哪个 donateTo
键的总数最高,从而节省额外的传递来计算最高的。
function findHighestSum(list) {
// collect cumulative totals
var totals = {}, highestTotal = 0, highestKey;
list.forEach(function(item) {
var key = item.donateTo;
if (!totals[key]) {
totals[key] = {amount: item.amount, cnt: 1};
} else {
totals[key].amount += item.amount;
totals[key].cnt++;
}
if (totals[key].amount > highestTotal) {
highestTotal = totals[key].amount;
highestKey = key;
}
});
// { donateTo: "Where Most Needed", total: 5000, count: 2}
return {donateTo: highestKey, total: highestTotal, count: totals[highestKey].cnt};
}
下面是一个使用下划线的实现:
var orgs = {};
_.each(donations, function(donation) {
if (orgs[donation.donateTo] == null)
orgs[donation.donateTo] = 0;
orgs[donation.donateTo] += donation.amount;
});
var amount = _.max(_.values(orgs));
var donateTo = _.invert(orgs)[amount];
var count = _.where(donations, {donateTo: donateTo}).length;
var result = {donateTo: donateTo, amount: amount, count: count};
console.log(result);
因为下划线很有趣!
_.chain(donations)
.reduce(function(m, c) {
var findItem = _.findWhere(m, { 'donateTo': c.donateTo});
if (findItem) {
findItem.count++;
findItem.total += c.amount;
} else {
m.push({
'donateTo':c.donateTo,
'count':1,
'total':c.amount});
};
return m; }, [])
.max(function(k) { return k.total})
.value();
使用下划线...
// reduce donations, finally returning object with largest amount total
var highest = _.reduce(donations, function(memo, item, index){
// add to amount total if group exists, else init group
if(memo[item.donateTo]){
memo[item.donateTo].amount += item.amount;
memo[item.donateTo].count++;
} else {
memo[item.donateTo] = {
donateTo: item.donateTo,
amount:item.amount,
count:1
};
}
// if it is last iteration...
if(index === donations.length - 1){
// extract the max value
memo = _.max(_.toArray(memo), function(item){
return item.amount;
});
}
return memo;
}, {});
使用下划线 js ...
// return the max (amount) of sorted, and collapsed array
var result = _.max( _.reduce( _.sortBy(donations, 'donateTo'), function(memo, item){
// if the last item has same key, update it (items are sorted by `donateTo`)
var _last = _.last(memo);
if(_last && _last.donateTo === item.donateTo){
_last.amount += item.amount;
_last.count++;
// otherwise create it
} else {
memo.push( _.extend( _.omit(item, 'date'), {'count':1} ) );
}
return memo
}, []), 'amount');
下划线高尔夫...
var h = {}, c={};
var result = _.max(donations, function(o){ var i = o.donateTo;
delete o.date; c[i] = ++c[i]||1; o.count=c[i];
return o.amount = h[i] = (h[i]||0)+o.amount
});