说我有这个数组:

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

本质上,特定月份应该有一个条目,表示index中的intermediaryArray。但是,在您的for循环中,每个intermediaryArray索引都针对所有月份进行此检查。让我们来试一下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],即每个月向其推送新元素。换句话说,您循环遍历intermediaryArray循环中的for循环,其中循环遍历月份,因为元素之间存在一一对应的关系。

这样的事情就足够了:

 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循环即可。希望它能使事情澄清并帮助您朝正确的方向开始。

08-17 00:52