Javascript 返回基于日期的平均测试结果数组

标签 javascript arrays average

假设我有这个数组:

testResults = [
    {
        dateCreated: "2014-07-12",
        score: 27.1
    },
    {
        dateCreated: "2014-05-11",
        score: 99.3,
    },
    {
        dateCreated: "2014-07-22",
        score: 88.8
    },
    {
        dateCreated: "2014-07-01",
        score: 33.3
    }
];

我想创建一个函数:

testResultsstartDateendDateinterval为参数,计算平均测试结果并返回结果是一个数组:

calculateTestAverages(testResults, "2014-04-01", "2014-07-30", "month");

会回来

testAverages = [0, 99.3, 0, 49.7]

我想现在我只想创建一个中间二维数组:

intermediaryArray = [ [0], [99.3], [0], [27.1, 88.8, 33.3] ]

因为计算这个中间数组的平均值很容易。

到目前为止我所得到的不起作用:

// takes a string date and converts it into a Date object.
var convertToDateObject = function(date){
    dateObject = new Date(date);
    return dateObject;
}

// takes a string date and returns the month.
var getMonth = function(date){
    return convertToDateObject(date).getMonth();
}

var calculateTestAverages = function(testResults, startDate, endDate, interval){

    var intermediaryArray = [];

    if( interval == "month" ){

        startingMonth = getMonth(startDate);
        endingMonth = getMonth(endDate);
        maxArrayIndex = endingMonth - startingMonth;

        for (var i = 0; i <= maxArrayIndex; i++){
            intermediaryArray[i] = [];
            for (var month = startingMonth; month <= endingMonth; month++){
                for (var testNumber = 0; testNumber < testResults.length; testNumber++){
                    if ( getMonth(testResults[testNumber].dateCreated) == month ){
                        intermediaryArray[i].push(testResults[testNumber].score);
                    };
                };
            };
        };
    };

    return intermediaryArray;

}

我已经在这个问题上停留了几个小时。我觉得此时我的大脑有点炸了。

最佳答案

我会先回答你的问题,然后再解释哪里出了问题。别担心,你的代码背后的逻辑绝对没问题。这只是放错位置的大括号,即}

让我们看看嵌套的 for 循环,看看它们是如何进行的:

 var intermediaryArray = []; //initialized earlier

 ...

 for (var i = 0; i <= maxArrayIndex; i++){
        intermediaryArray[i] = [];
        for (var month = startingMonth; month <= endingMonth; month++){
            for (var testNumber = 0; testNumber < testResults.length; testNumber++){
                if ( getMonth(testResults[testNumber].dateCreated) == month ){
                    intermediaryArray[i].push(testResults[testNumber].score);
                };
            };
        };
    };

在您提供的测试用例中,intermediaryArray 的长度为 4,计算完美。最外层的 for 循环运行四次。对于每次迭代,您都执行此部分操作:

  for (var month = startingMonth; month <= endingMonth; month++){
        for (var testNumber = 0; testNumber < testResults.length; testNumber++){
            if ( getMonth(testResults[testNumber].dateCreated) == month ){
                intermediaryArray[i].push(testResults[testNumber].score);
            };
        };
    };

上面的代码基本上从 startingMonth 循环到 endingMonth 并找到 testResulsts 数组那个月 并且应该将其推送到 intermediaryArray

本质上,应该有一个特定月份的一个条目,表示intermediaryArray 中的索引。但是,在针对 intermediaryArrayevery 索引的 for 循环中,您针对所有 月份执行此检查。让我们为 i = 0 做一个试运行:

 i = 0
 ----------- 
 startingMonth = 4,
 endingMonth = 7

 month = 4 : Nothing gets pushed into intermediaryArray[0]
 month = 5 : {dateCreated: "05/11/2014",score: 99.3} gets pushed into intermediaryArray[0]
 month = 6 : Nothing gets pushed
 month = 7 : The remaining 3 tests get pushed into intermediaryArray[0]

Ultimately all the results get pushed into intermediaryArray[0] as we did not change i with the month variable

这就是为什么您在最终返回的 intermediaryArray 中将所有 testResults 插入所有循环末尾的原因。

解决方法非常简单,您初始化 intermediaryArray 一次,然后填充 intermediaryArray[i]每个向其推送新元素月。换句话说,您在 for 循环中循环遍历 intermediaryArray,在循环中遍历月份,因为元素。

像这样就足够了:

 for (var i = 0; i <= maxArrayIndex; i++){
        intermediaryArray[i] = [];  //Initialize the empty array here based on the size
     };

 for (var month = startingMonth,i=0; month <= endingMonth; month++,i++){
 //Simply update the value of i when you update the value of month. 
 //You don't have to enclose the whole thing into the loop that initialises intermediaryArray

       for (var testNumber = 0; testNumber < testResults.length; testNumber++){
                if ( getMonth(testResults[testNumber].dateCreated) == month ){
                    intermediaryArray[i].push(testResults[testNumber].score);
                };
       };
  };

在对 for 循环进行编码之前,最好计划一下我们在 for 循环上强制执行的约束。了解数组的遍历方式和存储方式后,只需将正确的条件插入 for 循环即可。希望它能澄清问题并帮助您朝着正确的方向开始。

关于Javascript 返回基于日期的平均测试结果数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26335618/

相关文章:

java - 使用 For 语句创建按钮并将它们添加到面板中?

java - 在Java中改组二维数组

c++ - 使用可变参数模板函数计算多个值的平均值

SPARQL 平均实例数

javascript - 尝试更改字符串 -> int

javascript - 关于HTTP文件上传的2个问题

java - 将元素添加到数组的最后一个位置

sql - 你如何确定Postgresql中一列的平均总数?

javascript - 使用 angularJS 显示密码的最后三个字符

javascript - 尽管被设置为特定 IP,但 socket.io 引用本地主机