Jquery 或 PHP 按日期字段分组对象数组

Posted

技术标签:

【中文标题】Jquery 或 PHP 按日期字段分组对象数组【英文标题】:Jquery or PHP group array of objects by date field 【发布时间】:2016-10-03 11:12:46 【问题描述】:

所以我有 json 响应,其中包含格式化用于创建图表的数据(使用 Canvas.js),它是一个对象数组,每个对象都包含 y 值(即 int)和标签(即 SQL 日期,如 2016- 02-06)。

我需要按日期对这些值进行分组并从中获取平均值。数据按日期排序。问题是,一天可以有随机点数,而另一天可能根本没有任何点数。所以,我需要一种周索引(计算一年中的周不是解决方案,因为可能有多年)。例如,我可以有以下数组:

[0] y: 2; label: 2016-04-01 // this is week 1 from the start of the array
[2] y: 6; label: 2016-04-02 // this is still week 1
[3] y: 1; label: 2016-04-13 // this is week 2
[4] y: 10; label: 2016-04-28 // this is week 3, if we count weeks only by appearance in the array, not by their actual position
[5] y: 2; label: 2016-05-01 // this is week 4
[6] y: 4; label: 2016-05-02 // still week 4

所以我需要以某种方式得到这些周,然后找到平均 y 值,所以从上面的数组中我会得到:

[0] y: 4; label: 2016-04-01
[2] y: 1; label: 2016-04-13
[3] y: 10; label: 2016-04-28
[4] y: 3; label: 2016-05-01

如何处理?我想我应该使用 php 方法并放弃尝试在前端制作它,或者可能有更简单的方法来处理这个问题?或者也许有允许自动分组的js图表插件?我将非常感谢任何可能的帮助!

【问题讨论】:

我建议在PHP端获取、排序、过滤数据,只用前端显示。 【参考方案1】:

你可以试试这样的:

$weeks = array();

foreach ($myData as $info) 
    $info = json_decode($info, true);
    $dateTime = new DateTime($info['label']);
    $weeksKey = $dateTime->format('W-Y');
    if (!isset($weeks[$weeksKey])) 
        $weeks[$weeksKey] = array('y' => $info['y'], 'label' => $dateTime, 'count' => 1);
     else 
        $weeks[$weeksKey]['y'] += $info['y'];
        $weeks[$weeksKey]['count']++;
        $weeks[$weeksKey]['label'] = $weeks[$weeksKey]['label'] > $dateTime
            ? $dateTime 
            : $weeks[$weeksKey]['label'];
    


$weeks = array_map(function($week) 
    return json_encode(array(
        'y' => $week['y'] / $week['count'],
        'label' => $week['label']->format('Y-m-d')
    ));
, $weeks);

var_dump($weeks); // or var_dump(array_values($weeks));

【讨论】:

【参考方案2】:

javascript 中,您可以使用一个对象来收集结果并使用一个数组。

本提案利用了RobG到Get week of year in JavaScript like in PHP的答案。

后面的代码是分组部分,取年和周数,收集数据进行平均计算。

// taken from https://***.com/a/6117889/1447675
Date.prototype.getWeekNumber = function () 
    var d = new Date(+this);
    d.setHours(0, 0, 0);
    d.setDate(d.getDate() + 4 - (d.getDay() || 7));
    return Math.ceil((((d - new Date(d.getFullYear(), 0, 1)) / 8.64e7) + 1) / 7);
;

var data = [ y: 2, label: '2016-04-01' ,  y: 6, label: '2016-04-02' ,  y: 1, label: '2016-04-13' ,  y: 10, label: '2016-04-28' ,  y: 2, label: '2016-05-01' ,  y: 4, label: '2016-05-02' ],
    avg = [];

data.forEach(function (a) 
    var year = a.label.slice(0, 4),
        week = new Date(a.label).getWeekNumber(),
        key = year + '|' + week;

    if (!this[key]) 
        this[key] =  count: 0, sum: 0, result:  y: 0, label: a.label  ;
        avg.push(this[key].result);
    
    this[key].count++;
    this[key].sum += a.y;
    this[key].result.y = this[key].sum / this[key].count;
, Object.create(null));

console.log(avg);

【讨论】:

以上是关于Jquery 或 PHP 按日期字段分组对象数组的主要内容,如果未能解决你的问题,请参考以下文章

按日期对具有日期字段的对象数组进行排序

PHP JSON 按相同值分组

MySQL(或 PHP?)按字段数据分组结果

JQuery使用日期对对象数组进行排序[重复]

linq.js 按javascript中的对象数组分组

在mysql和php中按日期范围分组