字典来自CSV(PHP)

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

Dictionary from CSV (PHP)

问题

我需要编写一个函数,该函数以温度作为输入,并返回一个字典,其中年份作为键,天数作为值。

CSV文件(年份、月份、日期、小时、温度):

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

天数是由另一个我已经有的函数计算的。它接受年份和温度,然后返回在给定年份中温度等于或低于给定温度的天数。由于数据是按小时而不是天计算的,所以需要找到小时数,然后除以24。

该函数:

function getDaysUnderTemp(int $targetYear, float $targetTemp): float {
    $file = fopen("data/temperatures-filtered.csv", "r");
    $hours = 0;

    while ($data = fgetcsv($file)) {
        if ($data[0] == $targetYear and $data[4] <= $targetTemp) {
            $hours++;
        }
    }

    fclose($file);
    return $hours / 24;
}

因此,例如,getDaysUnderTemp(2019, -10) 返回 13.92

以下是我要讨论的函数:

function getDaysUnderTempDictionary(float $targetTemp): array {
    $file = fopen("data/temperatures-filtered.csv", "r");
    $result = [];

    while ($data = fgetcsv($file)) {
        ???
    }
    
    fclose($file);
    return $result;
}

问题是,我不理解如何在这个新函数中实现已经编写的函数,然后从所有这些数据创建所需的字典。

期望的输出:

getDaysUnderTempDictionary(-10);

Array
(
    [2019] => 3.88
    [2020] => 0.21
    [2021] => 13.92
)
英文:

I need to write a function that takes temperature as an input and returns a dictionary with years as keys and number of days as values.

CSV file (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

The number of days is calculated by another function which I already have. It takes a year and a temperature 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, the number of hours is found and then divided by 24.

The function:

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

    $file = fopen(&quot;data/temperatures-filtered.csv&quot;, &quot;r&quot;);
    $hours = 0;

    while ($data = fgetcsv($file)) {
        if ($data[0] == $targetYear and $data[4] &lt;= $targetTemp) {
            $hours ++;
        }
    }

    fclose($file);
    return $hours / 24;
}

So as an example getDaysUnderTemp(2019, -10) returns 13.92.

This is a function I am asking about as I'm not sure how it might be done:

function getDaysUnderTempDictionary(float $targetTemp): array {
    $file = fopen(&quot;data/temperatures-filtered.csv&quot;, &quot;r&quot;);

    while ($data = fgetcsv($file)) {
        ???
    }
    
    fclose($file);
    return [];
}

The problem is I don't understand how an already written function could be implemented in this new one, and then create a required dictionary from all this data.

Desired output:

getDaysUnderTempDictionary(-10);

Array
(
    [2019] =&gt; 3.88
    [2020] =&gt; 0.21
    [2021] =&gt; 13.92
)

答案1

得分: 0

如果我在做这个,我会将所有数据以原始形式读入数组,然后生成我需要的其他结构。

我将以类的形式编写这个:

class TempCalculator {
    private $data;
    private $arr;

    const YEAR = 0;
    const TEMP = 4;

    public function __construct($filename) {
        $this->data = array_map('str_getcsv', file($filename));
    }

    public function getHoursBelowTemperature($temperature) : array {
        $this->arr = array();

        foreach ($this->data as $row) {
            $year = $row[self::YEAR];
            $temperatureValue = floatval($row[self::TEMP]);
            if ($temperatureValue < $temperature) {
                if (!array_key_exists($year, $this->arr)) {
                    $this->arr[$year] = 0;
                }
                $this->arr[$year]++;
            }
        }
        // 遍历数组,将所有小时数除以24
        array_walk($this->arr, function (&$value) {
            $value /= 24;
        });
        return $this->arr;
    }

    public function getDaysUnderTemp($year, $temp) : float {
        $hours = 0;
        foreach ($this->data as $row) {
            if ($row[self::YEAR] == $year && $row[self::TEMP] <= $temp) {
                $hours++;
            }
        }
        return $hours / 24;
    }    
}

// 可以这样调用它:
$tempCalculator = new TempCalculator('temperatures.csv');
$result = $tempCalculator->getHoursBelowTemperature(0);
print_r($result);

$result2 = $tempCalculator->getDaysUnderTemp(1.5);
print_r($result2);

只有代码部分被翻译。

英文:

If I were doing this, I would read all the data into an array in raw form
then produce whatever other structures I needed.

I am going to write this as a class:

class TempCalculator {
    private $data;
    private $arr;

    const YEAR = 0;
    const TEMP = 4;

    public function __construct($filename) {
        $this-&gt;data = array_map(&#39;str_getcsv&#39;, file($filename));
    }

    public function getHoursBelowTemperature($temperature) : array {
        $this-&gt;arr = array();

        foreach ($this-&gt;data as $row) {
            $year = $row[self::YEAR];
            $temperatureValue = floatval($row[self::TEMP]);
            if ($temperatureValue &lt; $temperature) {
                if (!array_key_exists($year, $this-&gt;arr)) {
                    $this-&gt;arr[$year] = 0;
                }
                $this-&gt;arr[$year]++;
            }
        }
        // Walk the array and divide all the hours by 24
        array_walk($this-&gt;arr, function (&amp;$value) {
            $value /= 24;
        });
        return $this-&gt;arr;
    }

    public getDaysUnderTemp($year, $temp) : float {
        $hours = 0;
        foreach ($this-&gt;data as $row) {
            if ($row[self::YEAR] == $targetYear &amp;&amp; $row[self::TEMP] &lt;= $targetTemp) {
                $hours ++;
            }
        }
        return $hours / 24;
    }    
}

You can call it like this:

$tempCalculator = new TempCalculator(&#39;temperatures.csv&#39;);
$result = $tempCalculator-&gt;getHoursBelowTemperature(0);
print_r($result);

$result2 = $tempCalculator-&gt;getDaysUnderTemp(1.5);
print_r($result2);

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

发表评论

匿名网友

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

确定