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

Solution 1

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

Solution 2

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;
}

Solution 3

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

Solution 4

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;
    }
}

Solution 5

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

Solution 6

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

Solution 7

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

Solution 8

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

Solution 9

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.

Solution 10

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

Solution 11

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

Solution 12

With array_reduce:

$names = array_reduce($array, function ($carry, $item) {
    return array_merge($carry, [$item['name']]);
}, []);

Solution 13

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

Solution 14

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.

Solution 15

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.