【问题标题】:Calculate the total sum for each category from a text file从文本文件中计算每个类别的总和
【发布时间】:2015-10-05 04:59:18
【问题描述】:

我有一个文本文件,我存储所有数据,如下所示:

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

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

在本例中,dept 类别的总和为 499expense 类别的总和为 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>';
    }
}

【问题讨论】:

  • 你试过了吗?
  • 您有当前正在打开/读取文本文件的代码吗?
  • 我已经在我的问题中添加了整个代码 :) 很抱歉造成混淆。我想我累了 -.- 现在这里的时钟是 00:47

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


【解决方案1】:

这应该适合你:

首先将您的文本文件读入带有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
)

到(第 2 点的数组):

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

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

然后您可以使用array_map() 为每个类别子数组调用array_sum()

因此,您将每个类别的所有值相加。所以你的数组(第 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) 从您的数组中获取所有类别,这将返回一个像这样的数组:

数组
(
    [0] => 部门
    [1] => 部门
    [2] => 费用
    [3] => 费用
)

然后使用array_keys()$category,我们只能从您想要的类别中获取该数组的键。例如expense 将是:

数组
(
    [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
        )
    //...
)

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

数组
(
    [0] => 2
    [1] => 3
)

然后结果/相交将是(注意:由于我们抓住了它们的相交键,我们必须将$keysarray_flip() 翻转):

数组
(
    [2] => 数组
        (
            [0] => 费用
            [1] => 测试 3
            [2] => 4387
            [3] => 0
        )

    [3] => 数组
        (
            [0] => 费用
            [1] => 测试 4
            [2] => 105
            [3] => 0
        )

)

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

数组
(
    [0] => 4387
    [1] => 105
)

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

4492

【讨论】:

  • 效果很好!但是我怎样才能把你的代码放在我的代码中呢?我坐在这里,头顶有一个大大的问号,在过去的 7 分钟里一直这样做。
  • @ErikEdgren 1) 首先,自从我的第一篇文章以来,我在答案中添加了更多细节,我希望这有助于更好地理解我的代码,并且您知道发生了什么 2) 对于您的do_maths() 函数我可以推荐你看这个:stackoverflow.com/q/18880772/3933332 3) 我真的看不透你的inifile() 函数,它应该做什么?你想用你的模式做什么?还有,如果我们谈论的是文本文件,为什么你会得到 .ini 文件的内容?
  • 感谢您的评论。 1)我已经阅读了您在回答中的最后一次编辑,但我想我已经厌倦了理解其中的一半。 2)谢谢你的链接。我会读 3) 我的inifile() 函数搜索您为$word 输入的类别并打印该类别的所有交易
  • @ErikEdgren (1) 如果看不懂卡住了,先睡觉再重新看) 2) 现在我看看应该怎么做。只有我不明白为什么 *.ini ?我以为我们在谈论一个文本文件?!
  • @ErikEdgren 不客气。给我一分钟,我将对我的答案进行编辑。
猜你喜欢
  • 2013-11-25
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多