从嵌套对象中获取不包括特定值的最大值属性
Getting the highest value excluding a certain value from a nested object property
我在这里必须做的事情非常具体,恐怕迭代逻辑超出了我的理解范围。好的...我有一个看起来像这样的对象:
var answers = {
cat1: {
q1: {
"question": "Why?",
"answer": "No",
"points": 6
},
q2: {
"question": "Why oh why?",
"answer": "50%",
"points": 15
},
q3: {
"question": "Is it true?",
"answer": "Maybe",
"points": 9
}
},
cat2: {
q1: {
"question": "Hello?",
"answer": "Hello",
"points": 0
},
q2: {
"question": "Why me?",
"answer": "Because",
"points": 9
},
q3: {
"question": "Is it true?",
"answer": "Maybe",
"points": 0
}
},
cat3: {
q1: {
"question": "why not?",
"answer": "I don't know",
"points": 15
},
q2: {
"question": "What?",
"answer": "That",
"points": 9
},
q3: {
"question": "Is it real?",
"answer": "Nope",
"points": 6
}
}
}
对于每个"category",我不知道的属性个名字,我需要找到最高点,不包括恰好15个点(也就是说,15 是一个特例,所以我认为 9 是 0、9 和 15 中最高的)对于类别中的 "q(n)" 个嵌套对象。
我想把这些高分中的每一个都加起来,可能是通过 +=ing 一个 "total" 变量。
我觉得好像我应该以某种方式使用 underscore.js 简化对象,这样我就只剩下 q1: 6
等,删除值为 15 的属性,然后使用下划线的 _.max()
函数在将这些高分相加之前为每个 q(n)
取最高分值。
在示例中,这将是 9 加 9 加 9 (27)。
感谢您的帮助。
您应该使用一个简单的 for
循环遍历 Object
的键,然后您可以总结结果。
var maxs = {},
tot = 0;
for (var i in answers) {
maxs[i] = 0;
for (var j in answers[i]) {
if (answers[i][j].points != 15) maxs[i] = Math.max(maxs[i], answers[i][j].points);
else delete answers[i][j];
// ^ delete the question if the score is 15
}
tot += maxs[i];
}
结果将是这样的:
maxs
> {
cat1: 9,
cat2: 9,
cat3: 9
}
tot
> 27
您可以使用_.mapObject
with a custom iteratee for _.max
按类别获得最高分:
var maxes = _.mapObject(answers, function (qs) {
var maxq = _.max(qs, function (q) {
return (q.points !== 15) ? q.points : -Infinity;
});
return maxq.points;
});
会输出
{cat1=9, cat2=9, cat3=9}
http://jsfiddle.net/v80z9w2y/ 演示
_.reduce
会让你得到总数:
var sum = _.reduce(maxes, function(memo, num){ return memo + num; }, 0);
http://jsfiddle.net/v80z9w2y/1/
如果您只对总和感兴趣,当然可以将这两个步骤结合起来:
var sum = _.reduce(answers, function (memo, qs) {
var maxq = _.max(qs, function(q) {
return (q.points !== 15) ? q.points : -Infinity;
});
return memo + maxq.points;
}, 0);
此代码无需任何库即可在任何现代浏览器中运行
var categories = [];
for (var cat in answers) {
categories.push(answers[cat]);
}
var sum = categories.map(function (cat) {
var highest = 0;
for (var q in cat) {
var question = cat[q];
if (question.points !== 15) {
highest = Math.max(highest, question.points);
}
}
return highest;
}).reduce(function (prev, current) {
return prev + current;
}, 0);
这是另一个使用下划线的版本:
var sum = _.reduce(answers, function(memo, cat){
return memo + _.max(_.without( _.pluck(cat, 'points'), 15) );
}, 0);
答案已经选好,但问题很有趣,所以这是我的尝试:
function getTotal(answers){
return Object.keys(answers).reduce(function(total, cat){
return total + Math.max.apply(window,
Object.keys(answers[cat]).map(function(question){
return answers[cat][question].points === 15 ? 0 : answers[cat][question].points;
})
);
},0);
}
我在这里必须做的事情非常具体,恐怕迭代逻辑超出了我的理解范围。好的...我有一个看起来像这样的对象:
var answers = {
cat1: {
q1: {
"question": "Why?",
"answer": "No",
"points": 6
},
q2: {
"question": "Why oh why?",
"answer": "50%",
"points": 15
},
q3: {
"question": "Is it true?",
"answer": "Maybe",
"points": 9
}
},
cat2: {
q1: {
"question": "Hello?",
"answer": "Hello",
"points": 0
},
q2: {
"question": "Why me?",
"answer": "Because",
"points": 9
},
q3: {
"question": "Is it true?",
"answer": "Maybe",
"points": 0
}
},
cat3: {
q1: {
"question": "why not?",
"answer": "I don't know",
"points": 15
},
q2: {
"question": "What?",
"answer": "That",
"points": 9
},
q3: {
"question": "Is it real?",
"answer": "Nope",
"points": 6
}
}
}
对于每个"category",我不知道的属性个名字,我需要找到最高点,不包括恰好15个点(也就是说,15 是一个特例,所以我认为 9 是 0、9 和 15 中最高的)对于类别中的 "q(n)" 个嵌套对象。
我想把这些高分中的每一个都加起来,可能是通过 +=ing 一个 "total" 变量。
我觉得好像我应该以某种方式使用 underscore.js 简化对象,这样我就只剩下 q1: 6
等,删除值为 15 的属性,然后使用下划线的 _.max()
函数在将这些高分相加之前为每个 q(n)
取最高分值。
在示例中,这将是 9 加 9 加 9 (27)。
感谢您的帮助。
您应该使用一个简单的 for
循环遍历 Object
的键,然后您可以总结结果。
var maxs = {},
tot = 0;
for (var i in answers) {
maxs[i] = 0;
for (var j in answers[i]) {
if (answers[i][j].points != 15) maxs[i] = Math.max(maxs[i], answers[i][j].points);
else delete answers[i][j];
// ^ delete the question if the score is 15
}
tot += maxs[i];
}
结果将是这样的:
maxs
> {
cat1: 9,
cat2: 9,
cat3: 9
}
tot
> 27
您可以使用_.mapObject
with a custom iteratee for _.max
按类别获得最高分:
var maxes = _.mapObject(answers, function (qs) {
var maxq = _.max(qs, function (q) {
return (q.points !== 15) ? q.points : -Infinity;
});
return maxq.points;
});
会输出
{cat1=9, cat2=9, cat3=9}
http://jsfiddle.net/v80z9w2y/ 演示
_.reduce
会让你得到总数:
var sum = _.reduce(maxes, function(memo, num){ return memo + num; }, 0);
http://jsfiddle.net/v80z9w2y/1/
如果您只对总和感兴趣,当然可以将这两个步骤结合起来:
var sum = _.reduce(answers, function (memo, qs) {
var maxq = _.max(qs, function(q) {
return (q.points !== 15) ? q.points : -Infinity;
});
return memo + maxq.points;
}, 0);
此代码无需任何库即可在任何现代浏览器中运行
var categories = [];
for (var cat in answers) {
categories.push(answers[cat]);
}
var sum = categories.map(function (cat) {
var highest = 0;
for (var q in cat) {
var question = cat[q];
if (question.points !== 15) {
highest = Math.max(highest, question.points);
}
}
return highest;
}).reduce(function (prev, current) {
return prev + current;
}, 0);
这是另一个使用下划线的版本:
var sum = _.reduce(answers, function(memo, cat){
return memo + _.max(_.without( _.pluck(cat, 'points'), 15) );
}, 0);
答案已经选好,但问题很有趣,所以这是我的尝试:
function getTotal(answers){
return Object.keys(answers).reduce(function(total, cat){
return total + Math.max.apply(window,
Object.keys(answers[cat]).map(function(question){
return answers[cat][question].points === 15 ? 0 : answers[cat][question].points;
})
);
},0);
}