tags:

views:

110

answers:

4

I have an array of objects and I want to convert it to an array of the result of a method of each of them. I can do this just fine, but I'm wondering if there is a cleaner / better approach to it maybe? For example, pretend this is what I'm working with and how I'm doing it now:

$objects = array();

$objects[] = new Dog();
$objects[] = new Dog();
$objects[] = new Dog();

$data = array();
foreach ($objects as $obj) {
  $data[] = $obj->myMethod();
}

Obviously this isn't super important, but it'd be nice to know about better ways to produce $data from $objects in the future. Any ideas? I was thinking there was some function for this, like array_map() or something but I'm not finding it.

+1  A: 

you could indeed use PHP's array_map() to do this

function cb($obj) { return $obj->myMethod(); }
.
.
$data = array_map(cb, $objects);
Scott Evernden
In php 5.3 you can use anonymous functions instead of `function cb($obj)`
Ivan Nevostruev
ah yeah 5.3 - the version that doesn't run properly in CLI mode for me on Windows 7 :( - but indeed that'd be a better way to do it...
Scott Evernden
This does look like the best way to go about it - thanks. And yeah I like the 5.3 version also but don't have it locally or on the server this is heading to.
pssdbt
+1  A: 

If you have php 5.3 or better, the neater way is to use array_map() with anonymous functions:

$retArray = array_map(function($o){ $o->myMethod(); }, $myArray);

If you don't have php 5.3, you are left with having to declare the function before hand and passing the function name to array_map()

Yacoby
A: 

TMTOWTDI, array_walk works similarly to array_map, but modifies the array in-place. Though array_map has the advantage of supporting multiple arrays:

http://us3.php.net/array%5Fwalk

pygorex1
+1  A: 

You could use a bit more OOP:ish approach using iterators.

class TrainedDogIterator implements Iterator {
    // implement methods on http://php.net/iterator
    public function current() {
        $dog = current($this->dogs); // $this->dogs would be your objects
        $trained_dog = $this->_trainDog($dog);
        return $trained_dog;
    }
    private function _trainDog($dog) {
        // do something with dog
        return $dog;
    }
}

Use it where you would use $data in your example.

$di = new TrainedDogIterator($dogs);
foreach($di as $dog) {
    // $dog is trained
}
chelmertz
This is a good/different approach on the problem, so thanks - could come in handy for other things as well. In this case I'm using a reused function that returns the array of objects, which in other cases need to be as-is. Though, implementing this approach may put the functionality in a more appropriate place in the code.
pssdbt
@pssdbt: the code was kind of a long shot, glad you enjoyed it :) If you give a bigger image of your system, you'd get more feedback about the overall design but I agree that you marked the right answer as correct in this case.
chelmertz