18

Is there a cleaner way than foreach to get an array of all "label" values?

$methods[0]['label'] = 'test';
$methods[0]['nr']    = 99;
$methods[1]['label'] = 'whatever';
$methods[1]['nr']    = 10;


foreach($methods as $method) {
    $methodsLabel[] = $method['label'];
}
2
  • I do not think foreach is unclean. Do you think it is unclean because you prefer functional programming? Commented Feb 24, 2011 at 17:56
  • 3
    I also think your code is just fine the way it is. Not only will it be fast, but also very easy to read and maintain... everyone knows how to look at a foreach! Commented May 22, 2013 at 10:02

7 Answers 7

29

No, there is no faster way than your implemented code. All other methods will be slower due to the overhead of a function call. For a small array the difference will be trivial, but for a large one (100 members or so, depending on implementation), the difference can be huge...

You could array_map it, but I'd stick with the raw PHP you posted above... It's easier to maintain and IMHO more readable...

After all, tell me which at a glance tells you what it does more:

$results = array();
foreach ($array as $value) {
    $results[] = $value['title'];
}

vs

$results = array_map(function($element) {
        return $element['title'];
    },
    $array
);

Or:

$callback = function($element) {
    return $element['title'];
}
$results = array_map($callback, $array);

Personally, the first does it for me the best. It's immediately obvious without knowing anything what it's doing. The others require knowledge of array_map semantics to understand. Couple that with the fact that array_map is slower, and it's a double win for foreach.

Code should only be as elegant as necessary. It should be readable above all else...

Sign up to request clarification or add additional context in comments.

2 Comments

I changed my description, I was not searching for a fast solution I was searching for a more cleaner solution.
@powtac: I still stand behind a straight foreach is more readable and easier to understand. And you're talking the same if not less code with the foreach, so I fail to see the benefit...
18

Sure, use array_map:

function getLabelFromMethod($method) {
   return $method['label'];
}

$labels = array_map('getLabelFromMethod', $methods);

If you are on PHP 5.3+, you can also use a lambda function:

$labels = array_map(function($m) {
   return $m['label'];
}, $methods);

4 Comments

Ok, but this are still 3 lines of code and also it requires to define an extra method. :( And for the moment I search for a nice solution in PHP < 5.3.
Beside array_map() there is no other solution?
I tried this for something similar and it was slow as hell. Faster just to use the foreach directly.
The foreach seems "ugly" for me in this case.
10

As of PHP 5.5+, this is exactly what array_column() does:

$methodsLabel = array_column($methods, 'label');

http://php.net/manual/function.array-column.php


3v4l example: https://3v4l.org/ZabAb

1 Comment

This is an interesting find as my Sublime Text doesn't know of that function and, therefore, doesn't provide auto completion for this.
6
array_map('array_shift', $methods);

Here assumption is that label will be the first element of each array.

3 Comments

@Gaurav @ircmaxell Okay, that's really nice. +1
Be very careful with this. If the assumption breaks for any reason (that the label is sorted differently for any reason), the code will return incorrect results.
@ircmaxell : Yes, need to be careful here.
5

On PHP 5.3+ you can use an anonymous function paired with array_map.

$methodsLabel = array_map(function($item) { return $item['label']; }, $methods);

2 Comments

Didn't realize you needed pre-PHP5.3.
Added it later... ;) After I saw your solution.
3

If label is first element in array then "current" with array_map will work fine.

array_map('current', $methods); 

Comments

3

Arrow functions have been introduced into PHP 7.4, which makes this a little bit cleaner.

$methodsLabel = array_map(fn($x) => $x['label'], $methods)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.