Reputation: 10809
I'm trying to make a function that will make a simple key->value list based on different parameters of an object. I have it working fine so long as each object is flat, but I'm in a situation now where I need the list's value to be based on a property that's an array. I can force it to assume this only goes one level deep, but how would I account for variable array depths?
I've changed it so that the value
argument can be passed an array that assumes the form $object->array[0][array[1]];
Hopefully you can tell from the code what I'm trying to do:
function make_list($data, $value = 'name', $key = 'id'){
$new_arr = array();
if (is_array($data))
{
if (isset($data[0]->weight)){
usort($data, function( $a, $b ){
return $a->weight == $b->weight ? 0 : ( $a->weight > $b->weight ) ? 1 : -1;
});
} elseif (isset($data[0]->value)){
usort($data, function( $a, $b ){
return $a->value == $b->value ? 0 : ( $a->value > $b->value ) ? 1 : -1;
});
}
foreach ($data as $key => $item)
{
if (!is_object($item))
{
$item = (object)$item;
}
if(isset($item->{$key}))
{
if (is_array($value)){
//account for nested value requests, assuming object properties that are arrays (seems to be what most of the database calls return) ['property', 'value']
foreach ($value as $key => $val) {
if($key == 0){
} else {
//don't know what to do here!
}
}
//THIS WOULD GENERALLY WORK IF ARRAY LENGTH IS 2 -- BUT SYNTAX IS FUBARED
$new_arr[$item->{$key}] = $item->{$value[0]}[{$value[1]}];
} else {
//THIS IS THE OLD BEHAVIOUR THAT WAS WORKING WHEN PASSING A STRING
$new_arr[$item->{$key}] = $item->{$value};
}
}
}
}
return $new_arr;
}
Once I figure that out I would make it so the $key can also be an array.
$data = new Customer();
$data->name = 'John Smith';
$data->age = 21;
$data->contact = array('street'=>'Main St', 'number'=>56, 'city_id'=>1, 'city'=>array('name'=>'Dorset'));
//Want these behaviours to work:
make_list($data, array('contact', 'city', 'name');
make_list($data, array('contact', 'street');
make_list($data, 'age');
Upvotes: 0
Views: 410
Reputation: 71404
You might look at recursion. I am not going to type out full solution here as I am not fully clear on what your intent here is. But rather I will give you a look at basic structure for typical recursive function to give you an idea of how it might be used.
function make_list_recursive($data, $input_key, $input_value) {
$return_list = array();
if(is_object($data)) {
// iterate publicly accessible properties of object
foreach($data as $key => $value) {
if (is_array($value)) {
// iterate over array and recurse each item
foreach($value as $array_val) {
$array_val_list = make_list_recursive($array_val, $input_key, $input_value);
$return_list = array_merge($return_list, $array_val_list);
}
} else {
// here is where you perform your key/value matching logic
// if the property matched your key/value criteria, then add it to $return_list
$return_list[{some key}] = {some value};
}
}
} else (is_array($data)) {
// iterate through array and recurse each item
foreach($data as $array_val) {
$array_val_list = make_list_recursive($array_val, $input_key, $input_value);
$return_list = array_merge($return_list, $array_val_list);
}
} else {
throw new Exception('You must pass object or array to this function');
}
return $return_list;
}
Upvotes: 2