从文本文件计算每个类别的总和

Calculate the total sum for each category from a text file

我有一个文本文件,我像这样存储所有数据:

dept|test-1|365|0
dept|test-2|134|0
expense|test-3|4387|0
expense|test-4|105|0

如何获得该类别中所有交易的每个类别的总和?

在此示例中,类别 dept 的总和为 499,类别 expense 的总和为 4'492

但是我如何在 PHP 内完成此操作?

这是我当前的代码:

function do_maths($expression) {
    eval('$o = ' . preg_replace('/[^0-9\+\-\*\/\(\)\.]/', '', $expression) . ';');
    return $o;
}

function inifile($fname, $word) {
    $contents = file_get_contents($fname.'.ini');
    $pattern = preg_quote($word, '/');
    $pattern = "/^.*$pattern.*$/m";

    if(preg_match_all($pattern, $contents, $matches)) {
        sort($matches[0]);

        # TABELL
        echo '<div class="table">';

            # LOOP
            foreach($matches[0] AS $found) {
                $transaction = explode('|', $found);

                echo '<div class="table-row'.($transaction[3] == 1 ? ' color-grey-light" title="'.$transaction[1].' är betalad"' : '"').'>';
                    echo '<div class="table-cell-left table-cell-left-width">';
                        echo $transaction[1];
                    echo '</div>';

                    echo '<div class="table-cell-right">';
                        echo '<span class="sum">';
                            echo do_maths($transaction[2]);
                        echo '</span> kr';
                    echo '</div>';
                echo '</div>';
            }

        echo '</div>';


    } else {
        echo '<div class="message color-blue">';
            echo 'Kunde inte hitta något';
        echo '</div>';
    }
}

这应该适合你:

首先将你的文本文件读入一个数组,file(). Then go through each array element(each line of your text file) and explode()它由|作为分隔符。

因此您的数组将从(第 1 点的数组)更改为:

Array
(
    [0] => dept|test-1|365|0
    [1] => dept|test-2|134|0
    [2] => expense|test-3|4387|0
    [3] => expense|test-4|105|0
)

到(第 2 点的数组):

Array
(
    [0] => Array
        (
            [0] => dept
            [1] => test-1
            [2] => 365
            [3] => 0
        )
    //...
)

在此之后,您可以遍历 $lines 数组并使用类别(子数组的第一个数组元素)作为索引并将值(第三个数组元素)添加到数组中。

那你可以打电话给array_sum() for each category subArray with array_map().

因此,您将每个类别的所有值加在一起。所以你的数组(第 3 点的数组):

Array
(
    [dept] => Array
        (
            [0] => 365
            [1] => 134
        )

    [expense] => Array
        (
            [0] => 4387
            [1] => 105
        )

)

会变成这样(第4点的数组):

Array
(
    [dept] => 499
    [expense] => 4492
)

最后只需遍历您的数组并显示您的数据:

<?php

    $lines = file("test.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);  //Array at point 1
    $lines = array_map(function($v){
        return explode("|", $v);
    }, $lines);  //Array at point 2

    foreach($lines as $line)
        $data[$line[0]][] = $line[2];
    //Array at point 3  
    $result = array_map("array_sum", $data); 
    //Array at point 4
    foreach($result as $category => $sum)
        echo $category . " = " . $sum . "<br>";

?>

输出:

dept = 499
expense = 4492

编辑:

所以我在您的函数中实现的代码将如下所示:

<?php

    function getCategoryFromFile($fileName, $category) {
        $lines = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

        $lines = array_map(function($v){
            return explode("|", $v);
        }, $lines);

        $keys = array_keys(array_column($lines, 0), $category);


        if(!empty($keys)) {

            echo '<div class="table">';

            foreach($keys as $key) {

                echo '<div class="table-row' . ($lines[$key][3] == 1 ? ' color-grey-light" title="' . $lines[$key][1] . ' är betalad"' : '"') . '>';
                    echo '<div class="table-cell-left table-cell-left-width">';
                        echo $lines[$key][1];
                    echo '</div>';                      
                echo '</div>';

            }

            echo '<div class="table-cell-right">';
                echo '<span class="sum">';
                    echo array_sum(array_column(array_intersect_key($lines, array_flip($keys)), 2));
                echo '</span> kr';
            echo '</div>';

            echo '</div>';

        } else {
            echo '<div class="message color-blue">';
                echo 'Kunde inte hitta något';
            echo '</div>';
        }

    }

    //As example
    getCategoryFromFile("test.txt", "expense");

?>

第一部分与我上面的代码相同。但是现在只循环遍历您想要的类别的数据,我们需要这些子数组的键。我们用这条线得到:

$keys = array_keys(array_column($lines, 0), $category);

所以基本上我们使用 array_column($lines, 0) 从您的数组中获取所有类别,这将 return 一个像这样的数组:

Array
(
    [0] => dept
    [1] => dept
    [2] => expense
    [3] => expense
)

然后用array_keys()$category我们只从你想要的类别中得到这个数组的键。例如 expense 将是:

Array
(
    [0] => 2
    [1] => 3
)

然后我们只检查我们是否有一些键,意味着一些具有您想要的类别的行。如果是,我们循环遍历这些键并使用它们来访问您想要的数据。

在 foreach 循环之后打印我们使用这一行的值的总和:

echo array_sum(array_column(array_intersect_key($lines, array_flip($keys)), 2));

但让我们分解一下。首先我们有:

array_intersect_key($lines, array_flip($keys))

我们用 array_intersect_key() 获取这两个数组的关键交集。在左侧,我们将数组 $lines 作为第一个数组,我们知道它看起来像这样:

Array
(
    [0] => Array
        (
            [0] => dept
            [1] => test-1
            [2] => 365
            [3] => 0
        )
    //...
)

现在在另一边作为第二个数组,我们有我们想要的类别的键,所以:

Array
(
    [0] => 2
    [1] => 3
)

然后 result/intersect 将是(注意:由于我们抓住了它们的交集,我们必须翻转 $keysarray_flip()):

Array
(
    [2] => Array
        (
            [0] => expense
            [1] => test-3
            [2] => 4387
            [3] => 0
        )

    [3] => Array
        (
            [0] => expense
            [1] => test-4
            [2] => 105
            [3] => 0
        )

)

我们从这个数组中得到每个子数组的第二列 array_column()。所以从上面的数组我们最终会得到:

Array
(
    [0] => 4387
    [1] => 105
)

然后最后我们用 array_sum() 得到这个数组的总和,你会得到:

4492