从嵌套对象属性中获取排除某个值的最高值

Getting the highest value excluding a certain value from a nested object property

本文关键字:最高值 排除 获取 嵌套 对象 属性      更新时间:2023-09-26

我在这里要做的是非常具体的,迭代逻辑恐怕超出了我的能力。可以我有一个看起来像这样的物体:

var answers = {
  cat1: {
    q1: {
      "question": "Why?",
      "answerswer": "No",
      "points": 6
    },
    q2: {
      "question": "Why oh why?",
      "answerswer": "50%",
      "points": 15
    },
    q3: {
      "question": "Is it true?",
      "answerswer": "Maybe",
      "points": 9
    }
  },
  cat2: {
    q1: {
      "question": "Hello?",
      "answerswer": "Hello",
      "points": 0
    },
    q2: {
      "question": "Why me?",
      "answerswer": "Because",
      "points": 9
    },
    q3: {
      "question": "Is it true?",
      "answerswer": "Maybe",
      "points": 0
    }
  },
  cat3: {
    q1: {
      "question": "why not?",
      "answerswer": "I don't know",
      "points": 15
    },
    q2: {
      "question": "What?",
      "answerswer": "That",
      "points": 9
    },
    q3: {
      "question": "Is it real?",
      "answerswer": "Nope",
      "points": 6
    }
  }
}

对于每个"类别"(我不知道其属性名称),我需要找到最高点,排除类别中"q(n)"嵌套对象的正好为15的点(也就是说,15是一种特殊情况,所以我认为9是0、9和15中的最高值)。

我想把这些高分中的每一个加在一起,可能是通过+=ing一个"总"变量。

我觉得我应该以某种方式使用underscore.js简化对象,这样我只剩下q1: 6等,删除值为15的属性,然后使用underscore的_.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_.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);

http://jsfiddle.net/v80z9w2y/2/

下面是另一个使用下划线的版本:

    var sum = _.reduce(answers, function(memo, cat){
        return memo + _.max(_.without( _.pluck(cat, 'points'), 15) );
    }, 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);

答案已经选定,但问题很有趣,所以我的尝试是:

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);
}

JSFiddle 上的演示