Search code examples
phparrayslaravelmultidimensional-arraygrouping

Group 2d array data by one column, preserve that column in each group and push another column's values as subarray elements


I'm trying to convert some array values (group then actually), but I don't know how to do that.

I have something like this:

[
 {
  "nsr": "000086310",
  "type": "3",
  "date": "2015-07-18",
  "time": "00:06",
  "pis": "12138790985"
 },
 {
  "nsr": "000086313",
  "type": "3",
  "date": "2015-07-18",
  "time": "00:33",
  "pis": "16073736879"
 },
 {
  "nsr": "000086316",
  "type": "3",
  "date": "2015-07-18",
  "time": "00:58",
  "pis": "16634402451"
 },
 {
  "nsr": "000086316",
  "type": "3",
  "date": "2015-07-19",
  "time": "00:58",
  "pis": "98127981729"
 },
 {
  "nsr": "000086316",
  "type": "3",
  "date": "2015-07-19",
  "time": "00:58",
  "pis": "12398712938"
 }
]

And I want to convert to this:

[
 "date" : "2015-07-18",
 "pis" : [
     "12138790985",
     "16073736879",
     "16634402451"
  ]
],
[
 "date" : "2015-07-19",
 "pis" : [
     "98127981729",
     "12398712938"
  ]
]

I tried to do something like this:

public function index()
{
    $this->setTxtData('../../txt_files/CAP  3 18 07 2015 FABRICA.txt');
    $txtdata = $this->getTxtData();

    $dataToCompare = array();

    foreach ($txtdata as $ponto) {
        $time = $ponto['time'];
        $date = $ponto['date'];
        $pis = $ponto['pis'];

//      $dataToCompare = array();
//      if (strpos($ponto['pis'], '00000000000') === false) {
//            $pis_temp[][''] = $ponto['pis'];
//        }

        if (isset($dataToCompare)) {
            foreach ($dataToCompare as $dateToSet) {
                if ($dateToSet['data'] == $date) {
                    $dateToSet['pis'][] = $pis;
                } else {
                    $dateToSet['data'] = $date;
                    $dateToSet['pis'][] = $pis;
                }
            }
        } else{
            $dataToCompare = array(
                [
                    'data' => $date,
                    'pis' => array($pis)
                ]
            );
        }
        $funcionario_id = DB::table('funcionario')
            ->select('id')
            ->where('pis_pasep', '=', $pis)
            ->pluck('id');

        if ($funcionario_id !== null) {

            $validate = DB::table('horas_trabalho')
                ->select('id')
                ->where('hora', '=', $time)
                ->where('data', '=', $date)
                ->where('funcionario_id', '=', $funcionario_id)
                ->pluck('id');

            if ($validate === null) {
                DB::table('horas_trabalho')
                    ->insert([
                            'hora' => $time,
                            'data' => $date,
                            'funcionario_id' => $funcionario_id
                    ]);
            }
        }
    }

    //-------------------------------------Lógica para faltas-----------------------------------


    /**
     * Pega o pis
     */
    $db_all_funcionarios = DB::table('funcionario')
        ->select('pis_pasep')
        ->where('pis_pasep', '!=', 0)
        ->get();

    foreach ($db_all_funcionarios as $pis) {
        if (strpos($pis->pis_pasep, '00000000000') !== true) {
            $global_pis[] = $pis->pis_pasep;
        }
    }

//    $faltantes = array_diff($pis_temp, $global_pis);

//    foreach ($faltantes as $faltante) {
//        DB::table('falta')
//            ->insert([
//               'data' => date('2015-07-16')
//            ]);
//    }

//    $ponto_db[] = DB::table('horas_trabalho')
//        ->join('funcionario', 'horas_trabalho.funcionario_id', '=', 'funcionario.id')
//        ->select('funcionario.nome', 'horas_trabalho.hora', 'horas_trabalho.data')
//        ->get();

    return $txtdata;
}

Solution

  • I see the date in your filename and think you want group all entities at all:

    $dataToCompare = array(
      'date' => $txtData[0]['date'],
      'pis' => array_map(function($el){return $el['pis'];}, $txtData)
    );
    

    For multiple dates:

    $hash = array();
    foreach ($txtData as $entity) {
      if (!isset($hash[$entity['date']])) $hash[$entity['date']] = array();
      $hash[$entity['date']][] = $entity['pis'];
    }
    $result = array();
    foreach($hash as $date=>$pis) {
      $result[] = array('date'=>$date, 'pis'=>$pis);
    }