遍历CSV文件中的一列(PHP)

huangapple go评论65阅读模式
英文:

Iterating through a column in a CSV file (PHP)

问题

function getDaysUnderTemp(int $targetYear, float $targetTemp): float {

    $inputFile = fopen("data/temperatures-debug.csv", "r");
    $totalHours = 0;

    while (!feof($inputFile)) {

        $file = fgetcsv($inputFile);

        $year = intval($file[0]);
        $hours = intval($file[3]);
        $temperature = floatval($file[4]);

        if ($year === $targetYear and $temperature <= $targetTemp) {
            $totalHours += $hours;
        }
    }

    fclose($inputFile);

    return $totalHours / 24;
}
英文:

I need to write a function that takes a year and a temperature as an input and returns how many days in a given year the temperature was equal to or below the given temperature. Since the data is about hours, not days, need to find the number of hours and divide it by 24.

Example: getDaysUnderTemp(2019, -10) returns 13.92.

CSV file looks like this (year, month, day, hour, temperature):

2019,1,1,0,0.1
2019,1,1,1,0.4
2019,1,1,2,0.8
2019,1,1,3,1.3
2019,1,1,4,1.8
...
2020,1,1,0,-3.9

So far my code looks like this (I'm new to php):

function getDaysUnderTemp(int $targetYear, float $targetTemp): float {

    $inputFile = fopen(&quot;data/temperatures-debug.csv&quot;, &quot;r&quot;);

    while (!feof($inputFile)) {

        $file = fgetcsv($inputFile);

        $hours = intval($file[3]);

        if (intval($file[0]) === $targetYear and floatval($file[4]) &lt;= $targetTemp) {
            ???
            return ??? / 24;
        }

        fclose($inputFile);
    }
    return &quot;error&quot;;
}

The problem is I don't know how to iterate through a column which represents the hours of a specific year, and then add them all together.

答案1

得分: 0

你离解决方案不远。

function getDaysUnderTemp($targetYear, $targetTemp): float 
{
    $hours = 0; 

    if ((($handle = fopen("data.csv", "r")) !== FALSE)) {

        while (($data = fgetcsv($handle)) !== FALSE) {
            // [0] -> year [1] -> month [2] -> day [3] -> hours [4] -> temp 
            if ($data[0] == $targetYear && $data[4] <= $targetTemp) {
                $hours += $data[3];
            } 
        }

        fclose($handle); 
    }

    return $hours / 24; 
}

你的逻辑是正确的,我只是对代码进行了重构并修复了一些小问题:

  • 你的函数被限定要返回一个 float 值,但由于你的代码中当没有找到匹配项时返回了字符串 "error",这会在某个时候引发异常。我现在返回 $hours / 24,所以问题得到解决;
  • 在每次迭代后,通过调用 fclose($inputFile) 来关闭文件指针,这可能会导致一些问题,因为 feof 函数需要一个有效但未关闭的流才能正常工作。现在,fclose 函数仅在工作完成时调用一次;

建议你使用 printf 函数来打印结果,如下所示:

printf("%.2f", getDaysUnderTemp(2019, -10));
英文:

you are not far from the solution.

function getDaysUnderTemp($targetYear, $targetTemp): float 
{
    $hours = 0; 

    if ((($handle = fopen(&quot;data.csv&quot;, &quot;r&quot;)) !== FALSE)) {

        while (($data = fgetcsv($handle)) !== FALSE) {
            // [0] -&gt; year [1] -&gt; month [2] -&gt; day [3] -&gt; hours [4] -&gt; temp 
            if ($data[0] == $targetYear &amp;&amp; $data[4] &lt;= $targetTemp) {
                $hours += $data[3];
            } 
        }

        fclose($handle); 
    }

    return $hours / 24; 
}

The logic you had was correct, I just refactored the code and fixed some small issues:

  • Your function is bound to return a float value but since in your code you are returning the string "error" when a match is not found It would have thrown an exception at some point. I am now returning $hours / 24 so now the problem is solved;
  • After each iteration, you close the pointer to file by calling fclose($inputFile), this can cause some problems since the feof function needs a valid stream not closed to work properly. Now the fclose function is called only once when the work is done;

For printing the results I suggest you to use the printf function as follows:

 printf(&quot;%.2f&quot;, getDaysUnderTemp(2019, -10); 

huangapple
  • 本文由 发表于 2023年2月19日 03:33:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75495896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定