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

时间:2015-07-15 22:42:33

标签: php file text sum file-get-contents

我有一个文本文件,我存储了所有这些数据:

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>';
    }
}

1 个答案:

答案 0 :(得分:2)

这应该适合你:

首先将您的文本文件读入包含file()的数组。然后遍历每个数组元素(文本文件的每一行)和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
)

to(第2点的数组):

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

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

然后,您可以使用array_sum()为每个类别subArray调用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");

?>

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

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

基本上我们使用array_column($lines, 0)从数组中获取所有类别,这将返回如下数组:

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
)

然后结果/相交将是(注意:由于我们抓住它们的交叉点,我们必须用array_flip()翻转$keys):

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

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

)

从这个数组中我们得到每个subArray的第二列array_column()。因此,从上面的数组我们将最终得到:

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

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

4492