26

I have an array of arrays, with the following structure :

array(array('page' => 'page1', 'name' => 'pagename1')
      array('page' => 'page2', 'name' => 'pagename2')
      array('page' => 'page3', 'name' => 'pagename3'))

Is there a built-in function that will return a new array with just the values of the 'name' keys? so I'd get:

array('pagename1', 'pagename2', 'pagename3')
Insane Skull
  • 9,220
  • 9
  • 44
  • 63
Skilldrick
  • 69,215
  • 34
  • 177
  • 229

15 Answers15

81

As of PHP 5.5 you can use array_column():

<?php
$samples=array(
            array('page' => 'page1', 'name' => 'pagename1'),
            array('page' => 'page2', 'name' => 'pagename2'),
            array('page' => 'page3', 'name' => 'pagename3')
            );
$names = array_column($samples, 'name');
print_r($names);

See it in action

John Conde
  • 217,595
  • 99
  • 455
  • 496
  • Nice, thanks John. I have been researching into PHP 5.5, but I hadn't seen this – Adam Elsodaney Apr 02 '13 at 10:49
  • 13
    This should be the correct answer by now since php has added the built in function which exactly what the OP is asking. – Mohammed Joraid Dec 31 '13 at 08:20
  • @John Conde, someone must have it in for you today as a lot of your posts are being flagged as low quality... – Option Apr 20 '18 at 06:40
  • @Option Thanks for the heads up. If they're flagging stuff like this I don't think anything is going to come of it. But they are wasting people's time which is a shame. – John Conde Apr 20 '18 at 11:53
  • @John, no problem whatsoever Im unsure if you can flag this to staff to place a prevention on it or not.. Nevertheless, I have marked all as fine as I'm sure others will too :) – Option Apr 20 '18 at 11:54
19

Why does it have to be a built in function? No, there is none, write your own.

Here is a nice and easy one, as opposed to others in this thread.

$namearray = array();

foreach ($array as $item) {
    $namearray[] = $item['name'];
}

In some cases where the keys aren't named you could instead do something like this

$namearray = array();

foreach ($array as $key => $value) {
    $namearray [] = $value;
}
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
Anti Veeranna
  • 11,485
  • 4
  • 42
  • 63
  • 1
    Okay, given your recent edit ('easy one, as opposed to others') I'll bite ;) If you turn your code into a real function as per the original request, it will be about as 'complex' as the the `array_map()` or `array_walk()` examples below, especially if you'd care to add an execution example. – Henrik Opel Sep 29 '09 at 23:12
  • Yeah I think mine is the most elegant given PHP's features and the first complete example. :) – fuentesjr Sep 30 '09 at 06:19
  • 1
    Hi, thanks. All I actually asked in my question was if there is a built-in function - I don't like to reinvent the wheel. You gave me an answer to that, and your solution is basically what I would have written. – Skilldrick Sep 30 '09 at 21:49
  • Will issue a notice or warning, if one of the arrays doesn't have a `name` entry. Just sayin' – DanMan Nov 14 '14 at 14:08
  • 5
    The correct answer to "Is there a built-in function?" is the answer of John Conde below. – ax. Feb 12 '16 at 08:34
  • why dnt you use array_column($mainArray,'column'); http://php.net/manual/en/function.array-column.php – Neethu George Oct 09 '17 at 06:58
14

Here's a functional way of doing it:

$data = array(
            array('page' => 'page1', 'name' => 'pagename1'),
            array('page' => 'page2', 'name' => 'pagename2'),
            array('page' => 'page3', 'name' => 'pagename3'));

$result = array_map(create_function('$arr', 'return $arr["name"];'), $data);
print_r($result);
fuentesjr
  • 50,920
  • 27
  • 77
  • 81
  • 2
    I like this, and the lambda in it fits nicely with my brain at the moment, as I've been learning Scheme. +1 – Skilldrick Sep 30 '09 at 21:48
5

Well there is. At least for PHP > 5.5.0 and it is called array_column

The PHP function takes an optional $index_keyparameter that - as per the PHP website - states:

$index_key

The column to use as the index/keys for the returned array. This value may be the integer key of the column, or it may be the string key name

In the answers here, i see a stripped version without the optional parameter. I needed it, so, here is the complete function:

if (!function_exists('array_column')) {
    function array_column($array, $column, $index_key = null) {
        $toret = array();
        foreach ($array as $key => $value) {
            if ($index_key === null){
                $toret[] = $value[$column];
            }else{
                $toret[$value[$index_key]] = $value[$column];
            }
        }
        return $toret;
    }
}
papas-source
  • 1,221
  • 1
  • 14
  • 20
1

Similar to fuentesjrs solution, but a bit more generic using array_walk() with a custom callback:

// Define the callback
function extract_named_sub_elements(&$item, $key, $name) {
  $item = $item[$name];
}

// Test data
$original = array(
  array('page' => 'page1', 'name' => 'pagename1'),
  array('page' => 'page2', 'name' => 'pagename2'),
  array('page' => 'page3', 'name' => 'pagename3'),
);

// Use a copy, as array_walk() operates directly on the passed in array
$copy = $original;

// Substitute 'name' with whatever element you want to extract, e.g. 'page'
array_walk($copy, 'extract_named_sub_elements', 'name');

print_r($copy);
Henrik Opel
  • 19,341
  • 1
  • 48
  • 64
1
if (!function_exists('array_column')) {
    function array_column($array,$column) {
    $col = array();
    foreach ($array as $k => $v) {
        $col[]=$v[$column];
    }
    return $col;
    }
}

This should work for php versions < 5.5 and degrade in case the function exist

Srok
  • 37
  • 4
1

Yes, there is a php built-in function called array_column which does what you are looking for.

You would call it something like $name_keys = array_column($array, 'name'); to get the result that you are looking for.

Please refer to the following entry in the PHP manual for more details:

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

kguest
  • 3,804
  • 3
  • 29
  • 31
Dinesh
  • 75
  • 1
  • 3
0

You can extend the ArrayIterator class and override the method mixed current(void).

class Foo extends ArrayIterator {
  protected $index;
  public function __construct($array, $index) {
    parent::__construct($array);
    $this->index = $index;
  }

  public function current() {
    $c = parent::current();
    return isset($c[$this->index]) ? $c[$this->index] : null;
  }
}

$a = array(
  array('page' => 'page1', 'name' => 'pagename1'),
  array('name' => '---'),
  array('page' => 'page2', 'name' => 'pagename2'),
  array('page' => 'page3', 'name' => 'pagename3')
);

$f = new Foo($a, 'page');
foreach($f as $e) {
  echo $e, "\n";
}

prints

page1

page2
page3
VolkerK
  • 95,432
  • 20
  • 163
  • 226
0

I don't think there is any need to have a built in function for this. There may be an array in your those array.

$samples=array(
            array('page' => 'page1', 'name' => 'pagename1'),
            array('page' => 'page2', 'name' => 'pagename2'),
            array('page' => 'page3', 'name' => 'pagename3')
            );

$output1=array();
$output2=array();
foreach($samples as $sample){
    array_push($output1,$sample['name']);
    $output2[]=array_splice($sample,1);

}

print_r($output1);
print_r($output2);

in $output1 is the output what you want if you want only to remove the 'page' indexing' part then $output2.

if you need all the values from the that array and indexes numerically the array then you can use

$array_1=array_values($samples); 

but what i understand, you didn't want this.

Imrul
  • 3,456
  • 5
  • 32
  • 27
0

With array_reduce:

$names = array_reduce($array, function ($carry, $item) {
    return array_merge($carry, [$item['name']]);
}, []);
Progrock
  • 7,373
  • 1
  • 19
  • 25
Tony Vance
  • 134
  • 1
  • what does array_reduce do? Please explain it rather than just paste some code without explanation. Cheers – Martin Oct 15 '20 at 20:09
  • @Martin agree it could do with some edit, but as Tony hasn't been seen since 2016 the onus falls on someone else. Most of the submissions could be improved. Especially as other questons redirect here. – Progrock Oct 15 '20 at 23:02
  • Intution here is that pushing/appending to the carry and then returning the carry would be more performant than many merges. – Progrock Oct 16 '20 at 08:57
  • @Progrock I saw this post was on the front page, so looked at what was "active today" and this answer was highlighted. I had overlooked the date of the answer and has assumed it was a new answer from a user. – Martin Oct 16 '20 at 10:13
0

Not a 'built-in', but short arrow functions make for abrreviated explicit coding (introduced in Php v7.4.) and can be used with array_map for array transformations.

Here applying a callback to each member of the array that returns the desired attribute from each subarray:

<?php
$data =
[
    ['page' => 'page1', 'name' => 'pagename1'],
    ['page' => 'page2', 'name' => 'pagename2'],
    ['page' => 'page3', 'name' => 'pagename3']
];

$names = array_map(fn($v) => $v['name'], $data);
var_export($names);

Output:

array (
    0 => 'pagename1',
    1 => 'pagename2',
    2 => 'pagename3',
  )

The OP posted this question before array_column exisited (from Php 5.5.0). This answers the original question with a short solution:

$names = array_column($data, 'name');

But a simple loop is also trite:

foreach($data as $item) $names[] = $item['name'];
Progrock
  • 7,373
  • 1
  • 19
  • 25
0

You can get column, bind key value as well:

$a = array(
          array(
            'id' => 5698,
            'first_name' => 'Peter',
            'last_name' => 'Griffin',
          ),
          array(
            'id' => 4767,
            'first_name' => 'Ben',
            'last_name' => 'Smith',
          ),
          array(
            'id' => 3809,
            'first_name' => 'Joe',
            'last_name' => 'Doe',
          )
        );

if you want only column then use:

$last_names = array_column($a, 'last_name');
print_r($last_names);
        

if you want to bind key and values then use:

$last_names = array_column($a, 'last_name', 'id');
print_r($last_names);
    
-1

Just to extend on some of the answers here, as of PHP 5.5, array_column is what you want.

It actually has a few possible uses.

Using the sample array below, here are the different ways to use array_column.

$a = array(
    array('id' => '1', 'name' => 'Joe'),
    array('id' => '2', 'name' => 'Jane')
);

Retrieving a single column as the array

$b = array_column($a, 'name');

Would give you. Notice the auto keys starting from 0, as per a normal array.

$b[0] = 'Joe';
$b[1] = 'Jane';

Retrieving the full array with a column as the index.

$c = array_column($a, NULL, 'id');

Would result in the following.

$c[1] = array('id' => '1', 'name' => 'Joe');
$c[2] = array('id' => '2', 'name' => 'Jane');

Notice how the column I selected as the third parameter becomes the key for each item and I get the full array by setting the second parameter to null.

Of course, the final usage is to set both the 2nd and 3rd params.

$d = array_column($a, 'name', 'id');

Would give you the following.

$d[1] = 'Joe';
$d[2] = 'Jane';

I personally use the full 3 params for creating select option lists. If I have a table with my options, I query the table and get the result and pass it into this to get a list with the key as the value and the label. This is a brilliant way for building info sets that need to intersect by the index as well.

crazeyez
  • 459
  • 4
  • 4
-1

I wanted to post here, even if this is an old question, because it is still very relevant and many developers do not use PHP >= 5.5

Let's say you have an array like this:

Array
(
    [files] => Array
        (
            [name] => Array
                (
                    [0] => file 1
                    [1] => file 2
                    [2] => file 3
                )

            [size] => Array
                (
                    [0] => 1
                    [1] => 2
                    [2] => 3
                )

            [error] => Array
                (
                    [0] => abc
                    [1] => def
                    [2] => ghi
                )

        )

)

and the output you want is something like this:

Array
(
    [0] => Array
        (
            [0] => file 1
            [1] => 1
            [2] => abc
        )

    [1] => Array
        (
            [0] => file 2
            [1] => 2
            [2] => def
        )

    [2] => Array
        (
            [0] => file 3
            [1] => 3
            [2] => ghi
        )

)

You can simply use the array_map() method without a function name passed as the first parameter, like so:

array_map(null, $a['files']['name'], $a['files']['size'], $a['files']['error']);

Unfortunately you cannot map the keys if passing more than one array.

Paul Allsopp
  • 622
  • 1
  • 9
  • 23
-1

There is a built-in function actually, it's called array_column(...).

Here is all you need to know about it : https://www.php.net/manual/fr/function.array-column.php