数组中的年份作为键,然后填充当年的许多日期
Years in Array to key, then populate with many dates in that year
所以我从数据库中提取了一个这样的数组:
Array
(
[0] => stdClass Object
(
[created] => 2012-08-22 00:00:00
)
[1] => stdClass Object
(
[created] => 2012-08-23 00:00:00
)
[2] => stdClass Object
(
[created] => 2012-08-24 00:00:00
)
[3] => stdClass Object
(
[created] => 2012-08-24 00:00:00
)
[4] => stdClass Object
(
[created] => 2012-08-24 00:00:00
)
...
目前有几千条记录...
据此,我正在尝试构建如下所示的数组
Array (
[2016] array (
[01] array(), //Jan
[02] array( //Feb
[01] = 8 // number of occurances
[02] = 6 // number of occurances
.... etc
),
... etc
)
[2015] array(
[01] array(), //Jan
[02] array(), //Feb
... etc
)
... etc...
)
我不完全确定如何完全动态地执行此操作(IE:不对年份键进行硬编码)。
我愿意接受其他从数据库中提取信息的方法,也可以使用 MySQL 而不是 PHP/foreach 在数千条记录上循环。
这并不重要,我在 PHP 5.6 和 MySQL 5.6.28 上使用 Codeigniter 3,所以我标记了它们。
编辑:如果你没猜到,我正在创建图表...
编辑
根据@WEBjuju 的要求,下面是我的工作方法。在此过程中,我发现我还需要全年和每月的总计。我还没有测试过它的速度。
// much of this function provided by Whosebug user @Webjuju
// http://whosebug.com/posts/41067942
$all_dates = $this->db->select('created')->order_by('created', 'ASC')->get('jobs')->result(); // produces original array above
foreach ($all_dates as $obj)
{
$stt = strtotime($obj->created);
list($year, $month, $day) = explode('-', date('Y-m-d', $stt));
@$target[$year]['total']++;
@$target[$year][$month]['total']++;
// increment the string for each occurrence of that day/month/year
@$target[$year][$month]['counts'][$day]++;
}
$minyear = 2012; // TODO: get this dynamically
$maxyear = date('Y');
for ($y = $minyear; $y <= $maxyear; $y++)
{
for ($m = 1; $m < 13; $m++)
{
$m01 = (strlen($m)<2) ? "0$m" : $m;
$days_in_m = date('t', strtotime("$y-$m-01"));
for ($d = 1; $d <= $days_in_m; $d++)
{
// single digit? add preceeding 0
$d01 = (strlen($d)<2) ? "0$d" : $d;
// if day isn't in array, add it with 0 as a value
if (empty($target[$y][$m01]['counts'][$d01])) $target[$y][$m01]['counts'][$d01] = 0;
// put in correct place but works for now
ksort($target);
ksort($target[$y]);
ksort($target[$y][$m01]);
ksort($target[$y][$m01]['counts']);
}
}
}
$data->trends = $target;
现在生成如下数组:
Array
(
[2013] => Array
(
[total] => 1510 // total for year
[01] => Array // Jan
(
[counts] => Array
(
[01] => 0 //Jan 1
[02] => 1 // Jan 2
[03] => 1 //...
[04] => 3
[05] => 0
[06] => 0
[07] => 2
[08] => 1
[09] => 2
[10] => 4
[11] => 5
[12] => 0
[13] => 0
[14] => 0
[15] => 5
[16] => 21
[17] => 0
[18] => 1
[19] => 0
[20] => 0
[21] => 0
[22] => 0
[23] => 3
[24] => 2
[25] => 13
[26] => 0
[27] => 0
[28] => 24
[29] => 4
[30] => 3
[31] => 6
)
[total] => 101 // total for Jan
)
...
// repeats for all years found in db
// and all months and days for those years.
我现在有了工作图...
对从数据库中提取的 $arr
进行一次循环即可:
foreach ($arr as $obj) {
$stt = strtotime($obj->created);
list($year, $month, $day) = explode('-', date('Y-m-d', $stt));
// @$target[$year][$month] = array(); // original OP request
// increment the string for each occurrence of that day/month/year
@$target[$year][$month][$day]++;
}
die('<pre>'.print_r($target,true));
制作中
Array
(
[2012] => Array
(
[08] => Array
(
[22] => 1
[23] => 1
[24] => 1
)
[09] => Array
(
[22] => 1
[23] => 1
)
)
[2013] => Array
(
[08] => Array
(
[24] => 2
)
)
)
(来自以下测试数据):
$_01 = new stdClass();
$_01->created = '2012-08-22 00:00:00';
$_02 = new stdClass();
$_02->created = '2012-08-23 00:00:00';
$_03 = new stdClass();
$_03->created = '2012-08-24 00:00:00';
$_04 = new stdClass();
$_04->created = '2012-09-22 00:00:00';
$_05 = new stdClass();
$_05->created = '2012-09-23 00:00:00';
$_06 = new stdClass();
$_06->created = '2013-08-24 00:00:00';
$_07 = new stdClass();
$_07->created = '2013-08-24 00:00:00';
$arr = [$_01, $_02, $_03, $_04, $_05, $_06, $_07];
编辑 - 填入零!
for ($y = $minyear; $y <= $maxyear; $y++) {
for ($m = 1; $m < 13; $m++) {
$m01 = (strlen($m)<2) ? "0$m" : $m;
$days_in_m = date('t', strtotime("$y-$m-01"));
for ($d = 1; $d <= $days_in_m; $d++) {
$d01 = (strlen($d)<2) ? "0$d" : $d;
if (empty($target[$y][$m01][$d01])) $target[$y][$m01][$d01] = 0;
}
}
}
然后是关键排序
foreach ($target as &$month) {
uksort($month, zeroonesort);
foreach ($month as $day) {
uksort($day, zeroonesort);
}
}
function zeroonesort($a, $b) {
$ai = (integer) $a;
$bi = (integer) $b;
// in php 7 use the spaceship operator <=>
// otherwise do it the old way
switch (true) {
case ($ai == $bi): return 0;
case ($ai > $bi): return 1;
case ($ai < $bi): return -1;
}
}
生产
Array
(
[2012] => Array
(
[01] => Array
(
[01] => 0
[02] => 0
[03] => 0
[04] => 0
[05] => 0
[06] => 0
[07] => 0
[08] => 0
[09] => 0
[10] => 0
[11] => 0
[12] => 0
[13] => 0
[14] => 0
[15] => 0
[16] => 0
[17] => 0
[18] => 0
[19] => 0
[20] => 0
[21] => 0
[22] => 0
[23] => 0
[24] => 0
[25] => 0
[26] => 0
[27] => 0
[28] => 0
[29] => 0
[30] => 0
[31] => 0
)
[02] => Array
(
[01] => 0
[02] => 0
[03] => 0
[04] => 0
[05] => 0
[06] => 0
[07] => 0
[08] => 0
[09] => 0
[10] => 0
[11] => 0
[12] => 0
[13] => 0
[14] => 0
[15] => 0
[16] => 0
[17] => 0
[18] => 0
[19] => 0
[20] => 0
[21] => 0
[22] => 0
[23] => 0
[24] => 0
[25] => 0
[26] => 0
[27] => 0
[28] => 0
[29] => 0
)
[03] => Array
(
等...
所以我从数据库中提取了一个这样的数组:
Array
(
[0] => stdClass Object
(
[created] => 2012-08-22 00:00:00
)
[1] => stdClass Object
(
[created] => 2012-08-23 00:00:00
)
[2] => stdClass Object
(
[created] => 2012-08-24 00:00:00
)
[3] => stdClass Object
(
[created] => 2012-08-24 00:00:00
)
[4] => stdClass Object
(
[created] => 2012-08-24 00:00:00
)
...
目前有几千条记录...
据此,我正在尝试构建如下所示的数组
Array (
[2016] array (
[01] array(), //Jan
[02] array( //Feb
[01] = 8 // number of occurances
[02] = 6 // number of occurances
.... etc
),
... etc
)
[2015] array(
[01] array(), //Jan
[02] array(), //Feb
... etc
)
... etc...
)
我不完全确定如何完全动态地执行此操作(IE:不对年份键进行硬编码)。
我愿意接受其他从数据库中提取信息的方法,也可以使用 MySQL 而不是 PHP/foreach 在数千条记录上循环。
这并不重要,我在 PHP 5.6 和 MySQL 5.6.28 上使用 Codeigniter 3,所以我标记了它们。
编辑:如果你没猜到,我正在创建图表...
编辑
根据@WEBjuju 的要求,下面是我的工作方法。在此过程中,我发现我还需要全年和每月的总计。我还没有测试过它的速度。
// much of this function provided by Whosebug user @Webjuju
// http://whosebug.com/posts/41067942
$all_dates = $this->db->select('created')->order_by('created', 'ASC')->get('jobs')->result(); // produces original array above
foreach ($all_dates as $obj)
{
$stt = strtotime($obj->created);
list($year, $month, $day) = explode('-', date('Y-m-d', $stt));
@$target[$year]['total']++;
@$target[$year][$month]['total']++;
// increment the string for each occurrence of that day/month/year
@$target[$year][$month]['counts'][$day]++;
}
$minyear = 2012; // TODO: get this dynamically
$maxyear = date('Y');
for ($y = $minyear; $y <= $maxyear; $y++)
{
for ($m = 1; $m < 13; $m++)
{
$m01 = (strlen($m)<2) ? "0$m" : $m;
$days_in_m = date('t', strtotime("$y-$m-01"));
for ($d = 1; $d <= $days_in_m; $d++)
{
// single digit? add preceeding 0
$d01 = (strlen($d)<2) ? "0$d" : $d;
// if day isn't in array, add it with 0 as a value
if (empty($target[$y][$m01]['counts'][$d01])) $target[$y][$m01]['counts'][$d01] = 0;
// put in correct place but works for now
ksort($target);
ksort($target[$y]);
ksort($target[$y][$m01]);
ksort($target[$y][$m01]['counts']);
}
}
}
$data->trends = $target;
现在生成如下数组:
Array
(
[2013] => Array
(
[total] => 1510 // total for year
[01] => Array // Jan
(
[counts] => Array
(
[01] => 0 //Jan 1
[02] => 1 // Jan 2
[03] => 1 //...
[04] => 3
[05] => 0
[06] => 0
[07] => 2
[08] => 1
[09] => 2
[10] => 4
[11] => 5
[12] => 0
[13] => 0
[14] => 0
[15] => 5
[16] => 21
[17] => 0
[18] => 1
[19] => 0
[20] => 0
[21] => 0
[22] => 0
[23] => 3
[24] => 2
[25] => 13
[26] => 0
[27] => 0
[28] => 24
[29] => 4
[30] => 3
[31] => 6
)
[total] => 101 // total for Jan
)
...
// repeats for all years found in db
// and all months and days for those years.
我现在有了工作图...
对从数据库中提取的 $arr
进行一次循环即可:
foreach ($arr as $obj) {
$stt = strtotime($obj->created);
list($year, $month, $day) = explode('-', date('Y-m-d', $stt));
// @$target[$year][$month] = array(); // original OP request
// increment the string for each occurrence of that day/month/year
@$target[$year][$month][$day]++;
}
die('<pre>'.print_r($target,true));
制作中
Array
(
[2012] => Array
(
[08] => Array
(
[22] => 1
[23] => 1
[24] => 1
)
[09] => Array
(
[22] => 1
[23] => 1
)
)
[2013] => Array
(
[08] => Array
(
[24] => 2
)
)
)
(来自以下测试数据):
$_01 = new stdClass();
$_01->created = '2012-08-22 00:00:00';
$_02 = new stdClass();
$_02->created = '2012-08-23 00:00:00';
$_03 = new stdClass();
$_03->created = '2012-08-24 00:00:00';
$_04 = new stdClass();
$_04->created = '2012-09-22 00:00:00';
$_05 = new stdClass();
$_05->created = '2012-09-23 00:00:00';
$_06 = new stdClass();
$_06->created = '2013-08-24 00:00:00';
$_07 = new stdClass();
$_07->created = '2013-08-24 00:00:00';
$arr = [$_01, $_02, $_03, $_04, $_05, $_06, $_07];
编辑 - 填入零!
for ($y = $minyear; $y <= $maxyear; $y++) {
for ($m = 1; $m < 13; $m++) {
$m01 = (strlen($m)<2) ? "0$m" : $m;
$days_in_m = date('t', strtotime("$y-$m-01"));
for ($d = 1; $d <= $days_in_m; $d++) {
$d01 = (strlen($d)<2) ? "0$d" : $d;
if (empty($target[$y][$m01][$d01])) $target[$y][$m01][$d01] = 0;
}
}
}
然后是关键排序
foreach ($target as &$month) {
uksort($month, zeroonesort);
foreach ($month as $day) {
uksort($day, zeroonesort);
}
}
function zeroonesort($a, $b) {
$ai = (integer) $a;
$bi = (integer) $b;
// in php 7 use the spaceship operator <=>
// otherwise do it the old way
switch (true) {
case ($ai == $bi): return 0;
case ($ai > $bi): return 1;
case ($ai < $bi): return -1;
}
}
生产
Array
(
[2012] => Array
(
[01] => Array
(
[01] => 0
[02] => 0
[03] => 0
[04] => 0
[05] => 0
[06] => 0
[07] => 0
[08] => 0
[09] => 0
[10] => 0
[11] => 0
[12] => 0
[13] => 0
[14] => 0
[15] => 0
[16] => 0
[17] => 0
[18] => 0
[19] => 0
[20] => 0
[21] => 0
[22] => 0
[23] => 0
[24] => 0
[25] => 0
[26] => 0
[27] => 0
[28] => 0
[29] => 0
[30] => 0
[31] => 0
)
[02] => Array
(
[01] => 0
[02] => 0
[03] => 0
[04] => 0
[05] => 0
[06] => 0
[07] => 0
[08] => 0
[09] => 0
[10] => 0
[11] => 0
[12] => 0
[13] => 0
[14] => 0
[15] => 0
[16] => 0
[17] => 0
[18] => 0
[19] => 0
[20] => 0
[21] => 0
[22] => 0
[23] => 0
[24] => 0
[25] => 0
[26] => 0
[27] => 0
[28] => 0
[29] => 0
)
[03] => Array
(
等...