我有一个文本文件,我存储了所有这些数据:
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>';
}
}
答案 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