0

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');

4
  • 3
    Have you considered recursion? Commented Jan 7, 2014 at 21:44
  • Yeah sorta.. (i tagged it up) we are not the best of friends though.. I don't really know how to apply it here (or most places tbh) Commented Jan 7, 2014 at 21:48
  • Can you post an example of what you expect the initial and modified arrays/objects/whatever to look like? Commented Jan 7, 2014 at 22:18
  • I put in example data and calls Commented Jan 8, 2014 at 14:35

1 Answer 1

2

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks that gives a good overview. It's a surprisingly strange way to think abt things for some reason!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.