39

Suppose I have simple class like:

class MyClass {
  private $_prop;
  public function getProp() {return $this->_prop;}
  [....]
}

Now what I want to do somwhere not in scope of MyClass is to get array of $_prop from array of objects of MyClass($objs). This of course can be done with code like this:

$props = array();
foreach ($objs as $obj) {
    $props[] = $obj->getProp();
}

However this takes quote some lines, esp when formated in this way (and I have to use such formatting). So question is: if it is possible to do this using array_map? One way would be to use create function, but I don't really like that in php(lambdas in php are at least awkward and if i understand correctly its performance is like that of evaled code, but performance is beside the point here). I have tired searching quite a bit and failed to find any definetive answer. But I kinda have a feeling that it's not possible. I tried things like array_map(array('MyClass', 'getProp'), $objs), but that does not work since method is not static.

Edit: I'm using php 5.3.

9
  • What's wrong with the foreach loop? It's only four lines of code. Which PHP version are you using? Commented Jul 27, 2011 at 6:59
  • 1
    It's just that array_map has potential to be way cleaner, and I like functional techniques. But of course php is not a functional language so... Still it would be cool if this could be done. Since in reality it seems like kinda trivial functionality for language to have, kinda. Commented Jul 27, 2011 at 7:03
  • What exactly could be cleaner? You pass the content of the array to the callback one by one. That's pretty much the same than in Ruby, Python and JavaScript. Commented Jul 27, 2011 at 7:39
  • Pseudo code array_map(array('MyClass', 'getProp'), $objs) where non static method will be called would be cleaner. One compact line. No need to create empty array. No need to manually loop and push objects onto array. Just give one array and take another. Of course this idea does not play well with oop and esp with dynamic lose typing that php uses... But still it could be done :) Commented Jul 27, 2011 at 7:46
  • 1
    But that's not what array_map does. It does callback($element) for each $element in array. What you describe would be $element->callback() instead. Commented Jul 27, 2011 at 7:49

1 Answer 1

37

In PHP 5.3 you can do:

$props = array_map(function($obj){ return $obj->getProp(); }, $objs);

(see anonymous functions)

Of course this will still be slower than using a for loop as you have one function invocation per element but I think this comes closest to what you want.

Alternatively, which also works in prior to PHP 5.3 and might fit better to your style guidelines:

function map($obj) {
    return $obj->getProp();
}

$props = array_map('map', $objs);

Or (again back to PHP 5.3) you could create a wrapper function like this (but this will be the slowest possibility I think):

function callMethod($method) {
    return function($obj) use ($method) {
        return $obj->{$method}();
    };
}

$props = array_map(callMethod('getProp'), $objs);
Sign up to request clarification or add additional context in comments.

12 Comments

You could even type hint the closure argument to trigger a fatal error if the object was not an instance of MyClass, eg function(MyClass $obj){...
The closure would only be created once when passed to array_map(). At a guess, I'd say this would be almost identical to the loop in terms of performance
I said I don't want lambda/anonymous functions. Besides now that I think I most likely could not write this according to coding style guidelines.
@morphles: Well, in your comment you say you like functional approaches but now you say you don't line anonymous functions. But they go hand and hand. As I said in my comment I would just go with the for loop then.
@morphles: PHP provides us many small functions which can be assembled to new more powerful ones. That's just how it is. It's not Python.
|

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.