【问题标题】:JavaScript; calculate a mean, excluding certain valuesJavaScript;计算平均值,不包括某些值
【发布时间】:2016-10-02 09:37:20
【问题描述】:

我的问题

我有一系列变量,由调查中的满意度得分填充。这些分数介于 1 到 10 之间,但也可以是 99,表示“我不知道”。

如果没有一系列的If语句,是否可以计算所有问题的平均值而不包括99s?

我的尝试

对于在下面的示例中检索问题数据的方式有点奇怪,我们深表歉意。 3 个问题中的每一个都有 3 个衡量标准,这些衡量标准都给出了满意度评级。我正在使用的 Confirmit 调查平台使用 f('x_y').get() 获取答案,其中 x = 问题 ID 和 y = 测量,因此f('q3_1').get() 返回问题 3 中第一个测量的分数。

var qList = ['q3', 'q4', 'q6']; // 3 questions, each containing 3 satisfaction scores

var output
var i
for (i = 0; i < qList.length; i++){ // For each question in qList...
    // Collect each satisfaction rating & convert to flaoting-point number:
    var sat1 = parseFloat( f(qList[i].concat('_1')).get() );
    var sat2 = parseFloat( f(qList[i].concat('_2')).get() );
    var sat3 = parseFloat( f(qList[i].concat('_3')).get() );

    // Calculate average satisfaction
    var satAvg = (sat1 + sat2 + sat3) / 3;

    if (satAvg == NaN){
        output = "<em>Did not answer</em>";
    } else {
        output = satAvg.toString().concat('/10');
    }

    // Write to open-text questions:
    f('av'.concat(i +1)).set(output)
}

上面填充的开放文本 av1、av2 和 av3 问题的内容被连接成电子邮件警报,保持此警报简短是需要平均的原因。显然,任何“我不知道”的回答都会影响这个平均值。

编辑: 根据下面@Cimbali 的回答,我现在将这些值放入一个数组中。这意味着不需要的答案(11 和空白)可以通过循环中的单个 if 语句排除:

var qList = ['q3', 'q4', 'q6'];

// Get satisfaction scores:
var i;
for (i = 0; i < qList.length; i++){
    var answers = [
        parseFloat( f(qList[i].concat('_1')).get() ),
        parseFloat( f(qList[i].concat('_2')).get() ),
        parseFloat( f(qList[i].concat('_3')).get() )
    ];

    // Remove "I don't know" (11) and blank answers:
    var y;
    for (y = 0; y < answers.length; y++){
        if ( answers[y] > 10 || isNaN(answers[y]) ){
            answers.splice(y, 1);
        }
    }

    // Calculate sum of remaining answers:
    var sum = 0;
    var x;
    for (x = 0; x < answers.length; x++){
        sum += answers[x];
    }

    // Calculate mean:
    var average = sum / answers.length;

    if ( isNaN(average) ){
        // If mean couldn't be calculated, just enter 'N/A':
        var output = "N/A"; 
    } else {
        // Round to 2 decimal places & add the '/10':
        var output = average.toFixed(2).concat("/10");
    }   

    // Write to open text questions:
    f('av'.concat(i +1)).set(output);
}

但是,我仍然有兴趣知道更快的方法。

【问题讨论】:

  • 数据在哪里?
  • 没有真正回答你的问题,但让这个更清洁的第一步是,恕我直言,将答案的获取与平均计算分开。这样可以更轻松地处理算法。

标签: javascript math mean


【解决方案1】:

尝试将它们放入一个数组和filtering the array

类似:

function validAnswer(n) { return !isNaN(n) && n <= 10; }
answers = [
    parseFloat( f(qList[i].concat('_1')).get() ),
    parseFloat( f(qList[i].concat('_2')).get() ),
    parseFloat( f(qList[i].concat('_3')).get() )
].filter(validAnswer);

answers 现在只包含有效答案。将数组的内容相加并除以它的长度以获得平均值。请记住,您可能根本没有有效的答案。

这对更大的数组更有意义,在这种情况下,您可能希望用循环填充数组,而不是像这样硬编码。

function validAnswer(n) { return !isNaN(n) && n <= 10; }

// use functions to populate the array, hardcoded for the example
answers = [1, 2, 11, "not a valid number", 10].filter(validAnswer);
average = answers.length > 0 ? answers.reduce((val, sum) => val + sum) / answers.length: "N/A";

console.log("valid answers are [" + answers + "], average = " + average);

【讨论】:

  • 虽然我可以看到这应该完全符合我的需要,但我收到了 Function Expected 错误,我认为来自 filter(validAnswer)我> 位...
  • @PangolinPaws validAnswer 有错误,我使用“and”而不是“&&”。它现在应该可以工作了。我还添加了一种更密集的方式来完成你拥有的整个身体循环。理解我所写内容的关键是:ternay operatorArray.reducearrow functions
猜你喜欢
  • 2018-04-09
  • 2019-08-28
  • 2021-11-22
  • 2019-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 2017-01-02
相关资源
最近更新 更多