I have some logic that is being used to sort data but depending on the user input the data is grouped differently. Right now I have five different functions that contain the same logic but different groupings. Is there a way to combine these functions and dynamically set a value that will group properly. Within the function these assignments are happening
For example, sometimes I store the calculations simply by:
$calcs[$meter['UnitType']['name']] = ...
but other times need a more specific grouping:
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] =...
As you can see sometimes it is stored in a multidiminesional array and other times not. I have been trying to use eval() but without success (not sure that is the correct approach). Storing the data in a temporary variable does not really save much because there are many nested loops and if statements so the array would have to be repeated in multiple places.
EDIT
I hope the following example explains my problem better. It is obviously a dumbed down version:
if(){
$calcs[$meter['UnitType']['name']] = $data;
} else {
while () {
$calcs[$meter['UnitType']['name']] = $data;
}
}
Now the same logic can be used but for storing it in different keys:
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;
}
}
Is there a way to abstract out the keys in the $calc[] array so that I can have one function instead of having multiple functions with different array keys?
You can use this library to get or set value in multidimensional array using array of keys:
to get value or:
to set
$data
as value.Would it not be easier to do the following
or you can use Objects
but I would advice you build your structure in arrays and then do!
or you can loop your first array into a new array!
Give it ago and see how the array structure comes out.
Try to use a switch case.
I agree with the comment on the OP by @Jake N that perhaps using objects is a better approach. Nonetheless, if you want to use arrays, you can check for the existence of keys in a conditional, like so:
On the other hand, if you want to use objects, you can create a
MeterReading
object type, and then addMeterReading
instances as array elements to your$calcs
array, like so:Obviously you can take this further, such as checking the existence of array keys in the object constructor, giving the object property
resource
a default value if not provided, and so on, but this is a start to an OO approach.You can use this if you want to get&set array values dynamically.
How it works:
Calling
getVal($data,array('foo','bar','2017-08'))
will return the equivalent of$data['foo']['bar']['2017-08']
.Calling
setVal($data,array('foo','bar','2017-08'),'hello')
will set value as if you called$data['foo']['bar']['2017-08'] = 'hello'
. non-existent keys will be created automatically by php magic.This can be useful if you want to build the structure of the array dynamically.
Here's a function I wrote for setting deeply nested members on arrays or objects:
Using your example data:
Results in output like:
The second argument to
dict_set()
is a$path
string in dot-notation. You can build this using dynamic keys with period delimiters between the parts. The function works with arrays and objects.It can also append incremental members to deeply nested array by using
[]
as an element of the$path
. For instance:parent.child.child.[]