2017-11-27 1 views
0

Ich habe einen scheinbar übermäßig komplexen Code geschrieben, um serialisierte Daten in ein reihenbasiertes Array zu konvertieren, das wiederum einen Grafik-Plug-in für ein Verkaufsberichts-Ledger ansteuert. Die Datenbankabfragen können nicht geändert werden. Noch können die Formulare die Datenbanken füttern (Beide sind Legacy). Daher müssen wir mit den Ausgaben arbeiten, die von vorhandenen Datenbank-Select-Abfragen bereitgestellt werden. Der Code, den ich geschrieben habe (unten), funktioniert in Ordnung, sieht aber schrecklich komplex aus. Hat jemand Ideen für eine effizientere Methode?Serialisierte Daten in spezifische Array-Struktur konvertieren

    //Database Select Queries generating one pair of month-cost rows for each property 
        $cost_amount_array[]=$row->cost_amount; //always a cost value and month returned by form 
        $cost_month_array[]=$row->cost_month; 

        //Serialized data outputs 
        $cost_amount_array[$p] = [cost_amount] => a:6:{i:0;s:3:"333";i:1;s:3:"111";i:2;s:3:"100";i:3;s:3:"200";i:4;s:3:"690";i:5;s:3:"777";} 
        $cost_month_array[$p]) = [cost_month] => a:6:{i:0;s:1:"9";i:1;s:2:"10";i:2;s:1:"8";i:3;s:1:"7";i:4;s:1:"6";i:5;s:1:"9";} 

      //Final Output Required: Feeds a grahic plug API.... 
       array 
       (
       array (month1, cost_amount 1) where the cost_amounts need to be summed due multiple if there are multiple form entries for a month 
       array (month2, cost_amount2) 
       etc 
       etc 
       ) 

Routine für die Erstellung der endgültigen Array.

//Count the property entries in the $finance_array (output array). 
    //For each property unserialize the (synchronised) month - cost data and put data into a temp array 

       for ($p=0; $p<$count_finance_array; $p++) //for each record in array 
       { 
        $list_count=count(unserialize($cost_type_array[$p])) +$list_count; //grab the number of cost entries and cumulatively count them 
        $C[]=unserialize($cost_amount_array[$p]); 
        $D[]=unserialize($cost_month_array[$p]); 
       } 

       //Remove top level array wrapper 
        foreach($C as $array){  
         foreach($array as $key=>$value){ 
          //echo "KEY:".$key; 
          //echo "VAL:".$value; 
          $cost_amount_out[]=(int)$value; 
         } 
        } 

        foreach($D as $array){  
         foreach($array as $key=>$value){ 
          //echo "KEY:".$key; 
          //echo "VAL:".$value; 
          $cost_month_out[]=$value; 
         } 
        } 


     //Remove duplicate months and add up the corresponding cost values if a connected month with a cost-value is duplicated hence deleted 

        $month_cost_row = array_unique($cost_month_out);//returns just the unique values 
        $month_cost_row = array_combine($month_cost_row, array_fill(0, count($month_cost_row), 0));// 

        foreach($cost_month_out as $k=>$v) { 
         $month_cost_row[$v] += (int)$cost_amount_out[$k]; 
        } 

      //Make the key - which are the months - become the first values of each sub array (ie first value in each month/cost_value row) 
        $month_cost_row_sorted = array_map 
        (function($k, $v) 
        { 
        return array($k, $v); 
        }, 
        array_keys ($month_cost_row), $month_cost_row 
        ); 

      //Sort the rows by first value ie month (numerically ascend) 
        usort($month_cost_row_sorted, "cmp"); 
        //print "<pre>"; 
        //print_r($month_cost_row_sorted); 
        //print "</pre>"; 

        function cmp($X, $Y) { 
        return $X[0] - $Y[0]; 
        } 
         //print "<pre>"; 
         //print_r($month_cost_row_sorted); 
         //print "</pre>"; 

Diese Routine erzeugt das benötigte Array-Format. Aber es ist so komplex. Kann es vereinfacht werden?

ps Das $ p ist eine Anzahl der Zeilen in der Datenbank, wobei jede Zeile eine Eigenschaft darstellt. Alle Formularseiten der Kosten- und Einkommensdaten werden serialisiert. Daher gibt es für jedes Ledger nur eine Eigenschaftsinstanz pro Eigenschaft und nicht Hunderte (dh eine Zeile pro Kosteneintrag). Bei der Serialisierung nach Eigenschaftszeile handelt es sich um die Komplexität auf der Ausgabeseite entsteht. Aber aus Sicht der Wartung macht es das Leben viel einfacher - neue Kosten- oder Einkommenszeilen usw. hinzuzufügen ist eine optionale Ergänzung in einer Dropdown-Box. Gleiches gilt für die Einkommensseite, die wiederum nur eine Erweiterung jeder Eigentumsreihe mit serialisierten Immobilieneinkommen darstellt. Es gibt auch (für jedes Ledger) eine Zeile für allgemeine Gemeinkosten. Ein Hauptbuch könnte also 4 Zeilen umfassen (eine pro 4 Immobilien mit serialisierten Einnahmen und Kosten) plus eine allgemeine Zeile für Kosten, die nicht einer bestimmten Immobilie zugeordnet werden können. Ein Ledger ist ein internes Wort für eine Analyse der Rentabilität von Immobiliengruppen.

+0

Was steht '$ p'? – Progrock

+0

Ich habe meine Frage erweitert, um Ihre Frage zu beantworten, Sir – jimshot

Antwort

0
<?php 
foreach($rows as $row) 
    $out[$row->cost_month] += $row->cost_amount; 
ksort($out); 
foreach($out as $k=>$v) 
    $result[] = [$k, $v]; 
+0

Danke. Ich bin mir nicht ganz sicher, wie das funktionieren würde. Was ist das Array $ rows in Bezug auf die Prozedur, die der Code, den ich geschrieben habe, deckt? – jimshot

+0

@jimshot, die '$ rows' repräsentieren die Datenbankauswahlschleife am Anfang Ihres Codes. – Progrock

Verwandte Themen