如何使用哈希图或数组映射返回总数最高的类别
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"
}
];
我怎样才能退回这样的东西?捐赠总额最高的donateTo
的捐款与该捐款总额和构成该总额的礼物计数一起退还。
{ donateTo: "Where Most Needed", total: 5000, count: 2}
我以前能够用MongoDB得到结果,但是因为我使用的是Meteor,所以聚合真的很丑陋,没有反应性。我宁愿获取光标,然后在客户端使用javascript函数来获取我需要的数据。
谢谢
下面是使用下划线的实现:
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);
您可以循环遍历项目并将它们分组到一个对象中,然后循环访问对象中的属性以查找最大数量:
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 Stackoverflow 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};
}
工作演示:http://jsfiddle.net/jfriend00/7cfdsftz/
因为下划线很有趣!
_.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
});
相关文章:
- 使用哈希图分配声音
- 如何将值存储在哈希图/数组中以便稍后进行比较
- 如何使用此 JavaScript 返回带有特定哈希标签的推文
- 咖啡脚本一行,用于创建带有变量键的哈希图
- 在应用脚本中读取哈希图
- 如何使用哈希图或数组映射返回总数最高的类别
- Javascript 函数返回“[对象对象]”而不是哈希
- 如何区分浏览器返回和用户手动更改位置哈希
- Chrome 不返回哈希值
- 有没有办法在javascript中创建哈希图并像添加和删除值一样对其进行操作
- 导演.js和涡轮链接 - 更改窗口哈希并使用然后返回
- 返回哈希时出现意外的令牌 { 错误
- 为什么从其他网络返回会保留最后一个哈希值,同时显示第一个哈希值的内容
- 如何根据值对哈希图进行排序
- JavaScript哈希图是如何实现的
- 为什么angularJs会更新数组/哈希图的所有元素,如果只有一个元素发生了变化
- 如何转换JavaScript哈希图
- 如何在javascript中检查此布尔哈希图是否为空
- 车把:从帮助程序返回哈希
- 检索哈希图的Ajax调用