2010-09-13 11 views
6

Ho una logica che viene utilizzata per ordinare i dati ma, a seconda dell'input dell'utente, i dati sono raggruppati in modo diverso. In questo momento ho cinque diverse funzioni che contengono la stessa logica ma diversi raggruppamenti. C'è un modo per combinare queste funzioni e impostare dinamicamente un valore che si raggruppa correttamente. All'interno della funzione queste assegnazioni sono accadendoCome impostare dinamicamente i tasti dell'array in php

Ad esempio, a volte posso conservare i calcoli semplicemente:

$calcs[$meter['UnitType']['name']] = ... 

ma altre volte bisogno di un raggruppamento più specifico:

$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] =... 

Come si può vedere a volte è memorizzato in una matrice multidimensionale e altre volte no. Ho cercato di usare eval() ma senza successo (non sono sicuro che sia l'approccio corretto). Memorizzare i dati in una variabile temporanea non risparmia molto perché ci sono molti cicli annidati e se le istruzioni devono essere ripetute in più punti.

EDIT

spero che il seguente esempio spiega il mio problema meglio. Si tratta ovviamente di una versione storditi:

if(){ 
    $calcs[$meter['UnitType']['name']] = $data; 
} else { 
    while() { 
     $calcs[$meter['UnitType']['name']] = $data; 
    } 
} 

Ora la stessa logica può essere utilizzato, ma per la memorizzazione in diverse chiavi:

if(){ 
    $calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data; 
} else { 
    while() { 
     $calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data; 
    } 
} 

C'è un modo per astrarre le chiavi nella $ calc [] array in modo che possa avere una funzione invece di avere più funzioni con chiavi di array diverse?

+6

Potrebbe essere gestito meglio utilizzando gli oggetti? –

+2

In realtà non capisco il problema. Stai cercando di interrogare queste strutture dati in modo uniforme? – erisco

+1

Ho apportato una modifica per aiutare a spiegare. Speriamo che aiuti. – Kramer

risposta

0

Non sarebbe più facile effettuare le seguenti operazioni

$calcs = array(
    $meter['Resource']['name'] => array(
     $meter['UnitType']['name'] => 'Some Value', 
     $meter['UnitType']['name2'] => 'Some Value Again' 
    ), 
); 

oppure è possibile utilizzare gli oggetti

$calcs = new stdClass(); 
$calcs->{$meter['UnitType']['name']} = 'Some Value'; 

ma vorrei consigliare a costruire la vostra struttura in array e poi fare!

$calcs = (object)$calcs_array; 

oppure è possibile collegare il primo array in un nuovo array!

$new = array(); 
$d = date('Y-m',$start); 
foreach($meter as $key => $value) 
{ 
    $new[$key]['name'][$d] = array(); 
} 

Daglielo e guarda come viene fuori la struttura dell'array.

+0

Non sono sicuro che la domanda fosse chiara. Ho apportato alcune modifiche per cercare di aiutare a spiegare. – Kramer

0

Prova a utilizzare un caso interruttore.

<?php 
$userinput = $calcs[$meter['UnitType']['name']] = $data;; 

switch ($userinput) { 
    case "useriput1": 
    while() { 
     $calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data; 
    } 
    break; 
    case "userinput2": 
    while() { 
     $calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data; 
    } 
    break; 

    ... 

    default: 
    while() { 
     $calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data; 
    } 
} 
?> 
0

Sono d'accordo con il commento del PO da @Jake N che forse l'uso di oggetti è un approccio migliore.Tuttavia, se si desidera utilizzare le matrici, è possibile verificare l'esistenza di chiavi in ​​un condizionale, in questo modo:

if(
    array_key_exists('Resource', $meter) 
) { 
    $calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data; 
} else { 
    $calcs[$meter['UnitType']['name']] = $data; 
} 

D'altra parte, se si desidera utilizzare gli oggetti, è possibile creare un tipo di MeterReading oggetto , e quindi aggiungere MeterReading casi come elementi di un array al vostro $calcs array, in questo modo:

// Object defintion 
class MeterReading { 
    private $data; 
    private $resource; 
    private $startDate; 
    private $unitType; 

    public function __construct(Array $meter, $start, $data) { 
     $this->unitType = $meter['UnitType']['name']; 
     $this->resource = $meter['Resource']['name']; 
     $this->startDate = date('Y-m',$start); 
    } 

    public function data() { 
     return $this->data; 
    } 

    public function resource() { 
     return $this->resource; 
    } 

    public function startDate() { 
     return $this->startDate; 
    } 

    public function unitType() { 
     return $this->unitType; 
    } 
} 

// Example population 
$calcs[] = new MeterReading($meter, $start, $data); 

// Example usage 
foreach($calcs as $calc) { 
    if($calc->resource()) { 
     echo 'Resource: ' . $calc->resource() . '<br>'; 
    } 
    echo 'Unit Type: ' . $calc->unitType() . '<br>'; 
    echo 'Start Date: ' . $calc->startDate() . '<br>'; 
    echo 'Data: ' . $calc->data() . '<br>'; 
} 

Ovviamente si può prendere questo ulteriore, come ad esempio la verifica dell'esistenza di chiavi dell'array nel costruttore dell'oggetto, dando la proprietà oggetto resource un valore predefinito se non fornito, e così via, ma questo è un inizio per a Approccio OO.

0

È possibile utilizzare questo se si desidera ottenere & impostare i valori di matrice in modo dinamico.

function getVal($data,$chain){ 
    $level = $data; 
    for($i=0;$i<count($chain);$i++){ 
     if(isset($level[$chain[$i]])) 
      $level = $level[$chain[$i]]; 
     else 
      return null; // key does not exist, return null 
    } 
    return $level; 
} 

function setVal(&$data,$chain,$value){ 
    $level = &$data; 
    for($i=0;$i<count($chain);$i++){ 
     $level = &$level[$chain[$i]]; // set reference (&) in order to change the value of the object 
    } 
    $level = $value; 
} 

Come funziona:

Calling getVal($data,array('foo','bar','2017-08')) restituirà l'equivalente di $data['foo']['bar']['2017-08'].

La chiamata a setVal($data,array('foo','bar','2017-08'),'hello') imposterà il valore come se si chiamasse $data['foo']['bar']['2017-08'] = 'hello'. le chiavi inesistenti verranno create automaticamente da php magic.

Questo può essere utile se si desidera creare la struttura dell'array in modo dinamico.

0

Ecco una funzione che ho scritto per l'impostazione membri profondamente nidificate su array o oggetti:

function dict_set($var, $path, $val) { 
    if(empty($var)) 
     $var = is_array($var) ? array() : new stdClass(); 

    $parts = explode('.', $path); 
    $ptr =& $var; 

    if(is_array($parts)) 
    foreach($parts as $part) { 
     if('[]' == $part) { 
      if(is_array($ptr)) 
       $ptr =& $ptr[]; 

     } elseif(is_array($ptr)) { 
      if(!isset($ptr[$part])) 
       $ptr[$part] = array(); 

      $ptr =& $ptr[$part]; 

     } elseif(is_object($ptr)) { 
      if(!isset($ptr->$part)) 
       $ptr->$part = array(); 

      $ptr =& $ptr->$part; 
     } 
    } 

    $ptr = $val; 

    return $var; 
} 

Utilizzando i dati di esempio:

$array = []; 

$array = dict_set($array, 'resource1.unit1.2017-10', 'value1'); 
$array = dict_set($array, 'resource1.unit2.2017-11', 'value2'); 
$array = dict_set($array, 'resource2.unit1.2017-10', 'value3'); 

print_r($array); 

Risultati in uscita come:

Array 
(
    [resource1] => Array 
     (
      [unit1] => Array 
       (
        [2017-10] => value1 
       ) 

      [unit2] => Array 
       (
        [2017-11] => value2 
       ) 

     ) 

    [resource2] => Array 
     (
      [unit1] => Array 
       (
        [2017-10] => value3 
       ) 

     ) 

) 

Il secondo argomento per dict_set() è una stringa $path in dot-notation. È possibile creare questo utilizzando chiavi dinamiche con delimitatori di periodo tra le parti. La funzione funziona con matrici e oggetti.

È inoltre possibile aggiungere membri incrementali ad array profondamente annidati utilizzando [] come elemento di $path. Ad esempio: parent.child.child.[]

Problemi correlati