现在,也许是因为我累了,但在过去的一个小时里,我让自己陷入了一个循环--漩涡试图以一种不同的方式排列一个数组(array_column(),array_map(),以及少量的foreach()和if() )--这个漩涡的结果让我非常困惑,以至于我再也看不见森林里的树木了。坦白地说,我甚至很惭愧地发布了我尝试过的意大利面代码:-)。
数组如下所示:
array (
0 =>
array (
0 => '29',
1 => '0m9-cart-main-app',
2 => '2108',
3 => '9',
),
1 =>
array (
0 => '16',
1 => '0m9-safe-box-server',
2 => '2017',
3 => '12',
),
2 =>
array (
0 => '2',
1 => '0m9art-main-app-nodejs',
2 => '2017',
3 => '2',
),
3 =>
array (
0 => '1',
1 => '0m9art-server-golang',
2 => '2017',
3 => '4',
),
4 =>
array (
0 => '17',
1 => '0m9panel',
2 => '2017',
3 => '7',
),
5 =>
array (
0 => '3',
1 => 'moli-server',
2 => '2017',
3 => '3',
),
6 =>
array (
0 => '2',
1 => 'igcc',
2 => '2017',
3 => '11',
),
7 =>
array (
0 => '26',
1 => '0m9-cart-main-app',
2 => '2108',
3 => '10',
),
8 =>
array (
0 => '18',
1 => '0m9-safe-box-python-app',
2 => '2108',
3 => '12',
),
9 =>
array (
0 => '1',
1 => '0m9art-evergreen-android-app',
2 => '2108',
3 => '5',
), ......数组继续进行(大约700行),其中array[0] = count、array[1] = name、array[2] = year、array[3] = month基本上是单个人的所有git存储库中所有提交的聚合,目标是每个项目每个月的工作负载分布近似。
我需要知道的是,对于每个MONTH of YEAR,NAME-COUNT (repos-提交)占MONTH-COUNT-OF-ALL-NAMES总量(每月总体提交)的大致百分比是多少。
所以,我相信有一个优雅的一行来解决这个可怕的数组,但我似乎不能再这样做了..
编辑I
我确信,我所做的一切只会使每个人更加困惑,但既然评论已经提出了--以下是我在重新排列数组方面的一些尝试:
数组起源于csv,因此
$csv = array_map('str_getcsv', file('git_stati.csv'));
给出上面张贴的原始数组。
`
// try I
foreach($csv as $line){
$i=1;
// $r_date[] = $line[2] . $line[3] ;
$r_date = $line[2] .'-'. $line[3] ;
$r_dater[$r_date.'-'.$line[1] ] = $line[0] ;
$r_new[$line[1]]= $line[0] ;
$i++;
}
`// try II
foreach($csv as $line){
if ( $line[2] == '2018' ){
$name[] = $line[1] ;
$count[$line[1] ] += $line[0];
}
if ( $line[2] == '2017' ){
$name[] = $line[1] ;
$count[$line[1] ] += $line[0];
}
}
// try III
// foreach($r_dater as $key => $val) {
// if(substr($key, 0, 6) == '2018-9'){
// $str2 = substr($key, 7);
// $special_items[$key] = $val;
// $repo_r[$str2]= $val;
// }
// }
// other failed confusing trials ...
highlight_string("<?php\n\$data =\n". var_export($r_dater, true) . ";\n?>");编辑II
它基本上是一个人在所有git存储库中提交的所有提交的聚合,目标是每个项目每个月的工作负载分布都很接近。
我需要知道的是,对于每个MONTH of YEAR,NAME-COUNT (repos-提交)占MONTH-COUNT-OF-ALL-NAMES总量(每月总体提交)的大致百分比是多少。
对于示例数组,所需的输出如下:
'2018-09 => array ( 'repo_name' => '0m9-cart-main-app', 'commits' => 29, '% of total commits for 2018-09 => 'x.xx%', ),
发布于 2018-10-15 12:29:35
解决方案:
Calcultaion使用两个数组-一个用于每个期间的产品计数,另一个用于每个期间的总计数。
PHP:
<?php
# Input
$input = array(
array (
0 => '20',
1 => '0m9-cart-main-app',
2 => '2108',
3 => '9',
),
array (
0 => '30',
1 => '0m9art-main-app-nodejs',
2 => '2108',
3 => '9',
),
array (
0 => '20',
1 => '0m9-cart-main-app',
2 => '2108',
3 => '10',
),
array (
0 => '2',
1 => '0m9art-main-app-nodejs',
2 => '2108',
3 => '10',
)
);
# Calculate product and total counts
$monthProducts = array();
$monthTotal = array();
foreach($input as $item) {
$count = $item[0];
$name = $item[1];
$year = $item[2];
$month = $item[3];
$period = $year.'-'.$month;
if (!array_key_exists($period, $monthTotal)) {
$monthTotal[$period] = 0;
}
$monthTotal[$period] += $count;
if (!array_key_exists($period, $monthProducts)) {
$monthProducts[$period] = array();
}
if (!array_key_exists($name, $monthProducts[$period])) {
$monthProducts[$period][$name] = 0;
}
$monthProducts[$period][$name] += $count;
}
# Approximate percentage and output by period
foreach($monthProducts as $period => $products) {
echo $period."<br>";
foreach($products as $name => $count) {
echo "Product '". $name. "' approximate percentage: ". round($count / $monthTotal[$period] * 100, 2), " %. <br>";
}
}
?>发布于 2018-10-15 12:10:56
在第一次找到所有唯一的年份之后,您可以使用MONTH-COUNT-OF-ALL-NAMES计算array_reduce:
$years = array_unique(array_column($data, 2));
$mcoan = array_reduce($data,
function ($c, $d) {
$c[$d[2]] += (int)$d[0];
return $c;
},
array_combine($years, array_fill(0, count($years), 0)));这提供了一个数组,类似于:
Array ( [2108] => 74 [2017] => 41 )然后,可以使用array_map向数组中的每个条目添加一个百分比。
$data = array_map(function ($v) use ($mcoan) {
$v[4] = round($v[0]/$mcoan[$v[2]]*100,2);
return $v;
},
$data);输出(用于您的小样本):
array (
0 =>
array (
0 => '29',
1 => '0m9-cart-main-app',
2 => '2108',
3 => '9',
4 => 39.19,
),
1 =>
array (
0 => '16',
1 => '0m9-safe-box-server',
2 => '2017',
3 => '12',
4 => 39.02,
),
2 =>
array (
0 => '2',
1 => '0m9art-main-app-nodejs',
2 => '2017',
3 => '2',
4 => 4.88,
),
3 =>
array (
0 => '1',
1 => '0m9art-server-golang',
2 => '2017',
3 => '4',
4 => 2.44,
),
4 =>
array (
0 => '17',
1 => '0m9panel',
2 => '2017',
3 => '7',
4 => 41.46,
),
5 =>
array (
0 => '3',
1 => 'moli-server',
2 => '2017',
3 => '3',
4 => 7.32,
),
6 =>
array (
0 => '2',
1 => 'igcc',
2 => '2017',
3 => '11',
4 => 4.88,
),
7 =>
array (
0 => '26',
1 => '0m9-cart-main-app',
2 => '2108',
3 => '10',
4 => 35.14,
),
8 =>
array (
0 => '18',
1 => '0m9-safe-box-python-app',
2 => '2108',
3 => '12',
4 => 24.32,
),
9 =>
array (
0 => '1',
1 => '0m9art-evergreen-android-app',
2 => '2108',
3 => '5',
4 => 1.35,
),
)发布于 2018-10-15 12:11:14
假设您的原始数组名为$data (而且我理解了您最初想要做的事情,但不完全确定),您可以这样做:
// sum up values for year and month in two-dimensional array
$sums = [];
foreach($data as $item) {
if(isset($sums[$item[2]][$item[3]])) {
$sums[$item[2]][$item[3]] += $item[0]; // add value, if entry for year and month already exists,
}
else {
$sums[$item[2]][$item[3]] = $item[0]; // otherwise assign as initial value
}
}
// update original array, adding calculated percentage as $item[4]
foreach($data as &$item) {
$item[4] = ($item[0] / $sums[$item[2]][$item[3]] * 100);
}
unset($item); // working with a reference above, so don’t forget to unset
var_dump($data);现在,对于您所展示的示例数据,这只会导致每个项的值为100,因为首先,每年只有一个条目-月组合。但是,如果您修改输入数据以生成适当的测试用例,则会看到相应的数字变化。
同样,不确定这是否正是你想要的,这方面的问题有点模糊。
https://stackoverflow.com/questions/52815979
复制相似问题