JavaScript的;计算平均值,排除某些值

时间:2016-06-02 14:58:59

标签: javascript math mean

我的问题

我有一系列变量填充了调查的满意度分数。这些分数介于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&amp;的内容。上面填充的av3问题被连接成一个电子邮件警报,保持此警报简短是为什么需要平均值。显然,任何“我不知道”的回应都会影响这种意思。

修改 根据@ Cimbali的答案,我现在将这些值放入一个数组中。这意味着循环中的单个if语句可以排除不需要的答案(11&amp; blanks):

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

但是,我仍然有兴趣了解更快的方法。

1 个答案:

答案 0 :(得分: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);