更好地重构地图功能

时间:2017-03-12 12:01:24

标签: php laravel collections laravelcollective

我目前正在重构我的方法。 我已经淘汰了很长的foreach,如果状态,但现在我在最后一次完成时有点挣扎,有一个很好的地图功能。

我的方法看起来像。

/**
 * @param \Illuminate\Support\Collection
 * @return array
 */
public static function convertTimesToChartData($times) {
    $clientTotal = '0';
    $arrayIndex = 0;
    $chartData = collect($times)->filter(function($item) {
        return !is_null($item->end_time);
    })->map(function($item) use(&$clientTotal, &$arrayIndex){
        $clients[$arrayIndex]['id'] = $item->client_id;
        $clients[$arrayIndex]['project_id'] = $item->project_id;
        $clients[$arrayIndex]['label'] = $item->company;
        $clients[$arrayIndex]['sec'] = $item->end_time->timestamp - $item->start_time->timestamp;
        $clientTotal += $item->end_time->timestamp - $item->start_time->timestamp;
        $arrayIndex++;
        return $clients;
    })->flatMap(function($item) { return $item; });


    return $chartData;
}

在这里,我有两个问题:

  1. 有没有更好的方法来分配数组?当我试图直接在回报中分配

            return [
            [$arrayIndex]['id'] => $item->client_id,
            [$arrayIndex]['project_id'] => $item->project_id,
            [$arrayIndex]['label'] => $item->company,
            [$arrayIndex]['sec'] => $item->end_time->timestamp - $item->start_time->timestamp,
        ];
    
  2. 但后来我得到一个未定义的索引错误。

    1. 返回汇总数组的最佳方法是什么?因为我有相同客户端的几个时间条目,所以最后,我只想要汇总秒。它适用于我的例子,但我认为有更好的方法来做到这一点。特别是因为我需要定义一个$ arrayIndex,我需要在map函数之外声明并引用它。不要以为这是最好的方式。
    2. 以下是原始资料来源:

          $projects = array();
          $projectTotal = '0';
          foreach($taskTimes as $time){
              if(!is_null($time->end_time))
              {
                  if (isset($projects[$time->project_id]))
                  {
                      $projects[$time->project_id]['sec'] += $time->end_time->timestamp - $time->start_time->timestamp;
                  } else
                  {
                      $projects[$time->project_id]['id'] = $time->client_id;
                      $projects[$time->project_id]['label'] = $time->company;
                      $projects[$time->project_id]['sec'] = $time->end_time->timestamp - $time->start_time->timestamp;
                  }
                  $projectTotal += $time->end_time->timestamp - $time->start_time->timestamp;
              }
          }
      

      感谢您的任何建议和帮助!

1 个答案:

答案 0 :(得分:1)

为了获得与原始foreach循环相同的结果,您可以这样:

$projects = collect($taskTimes)
    ->filter(function ($time) {
        return !is_null($time->end_time);
    })
    ->groupBy('project_id')
    ->map(function ($group) {
        $group = collect($group);

        return [
            'id'         => $group->first()->client_id,
            'project_id' => $group->first()->project_id,
            'label'      => $group->first()->company,
            'sec'        => $group->sum(function ($item) {
                return $item->end_time->timestamp - $item->start_time->timestamp;
            }),
        ];
    });

$projectsTotal = $projects->sum('sec');

我已将project_id添加到生成的数组中,因为它包含在convertTimesToChartData()方法示例中

希望这有帮助!