Damon
Damon

Reputation: 10809

Retrieving a value dynamically when depth of array is unknown

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

Answers (1)

Mike Brant
Mike Brant

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

Related Questions