array_column

(PHP 5 >= 5.5.0, PHP 7)

array_column返回数组中指定的一列

说明

array array_column ( array $input , mixed $column_key [, mixed $index_key = null ] )

array_column() 返回input数组中键值为column_key的列, 如果指定了可选参数index_key,那么input数组中的这一列的值将作为返回数组中对应值的键。

参数

input

需要取出数组列的多维数组。 如果提供的是包含一组对象的数组,只有 public 属性会被直接取出。 为了也能取出 private 和 protected 属性,类必须实现 __get()__isset() 魔术方法。

column_key

需要返回值的列,它可以是索引数组的列索引,或者是关联数组的列的键,也可以是属性名。 也可以是NULL,此时将返回整个数组(配合index_key参数来重置数组键的时候,非常管用)

index_key

作为返回数组的索引/键的列,它可以是该列的整数索引,或者字符串键值。

返回值

从多维数组中返回单列数组。

更新日志

版本 说明
7.0.0 input 参数现在可以是包含对象的数组。

范例

Example #1 从结果集中取出first names列

<?php
// Array representing a possible record set returned from a database
$records = array(
    array(
        
'id' => 2135,
        
'first_name' => 'John',
        
'last_name' => 'Doe',
    ),
    array(
        
'id' => 3245,
        
'first_name' => 'Sally',
        
'last_name' => 'Smith',
    ),
    array(
        
'id' => 5342,
        
'first_name' => 'Jane',
        
'last_name' => 'Jones',
    ),
    array(
        
'id' => 5623,
        
'first_name' => 'Peter',
        
'last_name' => 'Doe',
    )
);
 
$first_names array_column($records'first_name');
print_r($first_names);
?>

以上例程会输出:

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

Example #2 从结果集中总取出last names列,用相应的id作为键值

<?php
// Using the $records array from Example #1
$last_names array_column($records'last_name''id');
print_r($last_names);
?>

以上例程会输出:

Array
(
    [2135] => Doe
    [3245] => Smith
    [5342] => Jones
    [5623] => Doe
)

Example #3 username 列是从对象获取 public 的 "username" 属性

<?php

class User
{
    public 
$username;

    public function 
__construct(string $username)
    {
        
$this->username $username;
    }
}

$users = [
    new 
User('user 1'),
    new 
User('user 2'),
    new 
User('user 3'),
];

print_r(array_column($users'username'));
?>

以上例程会输出:

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

Example #4 获取 username 列,从对象通过魔术方法 __get() 获取 private 的 "username" 属性。

<?php

class Person
{
    private 
$name;

    public function 
__construct(string $name)
    {
        
$this->name $name;
    }

    public function 
__get($prop)
    {
        return 
$this->$prop;
    }

    public function 
__isset($prop) : bool
    
{
        return isset(
$this->$prop);
    }
}

$people = [
    new 
Person('Fred'),
    new 
Person('Jane'),
    new 
Person('John'),
];

print_r(array_column($people'name'));
?>

以上例程会输出:

Array
(
    [0] => Fred
    [1] => Jane
    [2] => John
)
如果不提供__isset(),会返回空数组。

User Contributed Notes

Dominik59 17-Aug-2017 11:26
Presented function is good when You want to flatten nested array base on only one column, but if You want to flatten whole array You can use this method:

/**
     * Method that transforms nested array into the flat one in below showed way:
     * [
     *      [
     *          [0]=>'today',
     *      ],
     *      [
     *          [0]=>'is',
     *          [1]=>'very',
     *          [2]=>   [
     *                      [0]=>'warm'
     *                  ],
     *      ],
     * ]
     *
     * Into:
     *
     * ['today','is','very','warm']
     *
     * @param $input
     * @return array
     */
    private function transformNestedArrayToFlatArray($input)
    {
        $output_array = [];
        if (is_array($input)) {
            foreach ($input as $value) {
                if (is_array($value)) {
                    $output_array = array_merge($output_array, $this->transformNestedArrayToFlatArray($value));
                } else {
                    array_push($output_array, $value);
                }
            }
        } else {
            array_push($output_array, $input);
        }

        return $output_array;
    }
robsonvnasc at gmail dot com 10-Aug-2017 02:11
Retrieve multiple columns from an array:

$columns_wanted = array('foo','bar');
$array = array('foo'=>1,'bar'=>2,'foobar'=>3);

$filtered_array = array_intersect_key(array_fill_keys($columns_wanted,''));

//filtered_array
// array('foo'=>1,'bar'=>2);
1184427175 at qq dot com 21-Jul-2017 11:52
//php < 5.5
if(function_exists('array_column'))
{
    function array_column($arr_data, $col)
    {
        $result = array_map(function($arr){return $arr[$col]}, $arr_data);
        return $result;
    }
}
katrinaelaine6 at gmail dot com 01-Mar-2017 04:13
array_column() will return duplicate values.

Instead of having to use array_unique(), use the $index_key as a hack.

**Caution: This may get messy when setting the $column_key and/or $index_key as integers.**

<?php

$records
= [
        [
'id' => 2135, 'first_name' => 'John' ],
    [
'id' => 3245, 'first_name' => 'Sally' ],
    [
'id' => 5342, 'first_name' => 'Jane' ],
    [
'id' => 5623, 'first_name' => 'Peter' ],
        [
'id' => 6982, 'first_name' => 'Sally' ]
];

print_r(array_unique(array_column($records, 'first_name')));

// Force uniqueness by making the key the value.
print_r(array_column($records, 'first_name', 'first_name'));
print_r(array_column($records, 'id', 'first_name'));

// Returns
/*

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

Array
(
    [John] => John
    [Sally] => Sally
    [Jane] => Jane
    [Peter] => Peter
)

Array
(
    [John] => 2135
    [Sally] => 6982
    [Jane] => 5342
    [Peter] => 5623
)

*/

?>
Carlos Granados 01-Oct-2016 12:41
Here's a neat little snippet for filtering a set of records based on a the value of a column:

<?php

function dictionaryFilterList(array $source, array $data, string $column) : array
{
   
$new     = array_column($data, $column);
   
$keep     = array_diff($new, $source);

    return
array_intersect_key($data, $keep);
 }

// Usage:

$users = [
    [
'first_name' => 'Jed', 'last_name' => 'Lopez'],
    [
'first_name' => 'Carlos', 'last_name' => 'Granados'],
    [
'first_name' => 'Dirty', 'last_name' => 'Diana'],
    [
'first_name' => 'John', 'last_name' => 'Williams'],
    [
'first_name' => 'Betty', 'last_name' => 'Boop'],
    [
'first_name' => 'Dan', 'last_name' => 'Daniels'],
    [
'first_name' => 'Britt', 'last_name' => 'Anderson'],
    [
'first_name' => 'Will', 'last_name' => 'Smith'],
    [
'first_name' => 'Magic', 'last_name' => 'Johnson'],
];

var_dump(dictionaryFilterList(['Dirty', 'Dan'], $users, 'first_name'));

// Outputs:
[
    [
'first_name' => 'Jed', 'last_name' => 'Lopez'],
    [
'first_name' => 'Carlos', 'last_name' => 'Granados'],
    [
'first_name' => 'John', 'last_name' => 'Williams'],
    [
'first_name' => 'Betty', 'last_name' => 'Boop'],
    [
'first_name' => 'Britt', 'last_name' => 'Anderson'],
    [
'first_name' => 'Will', 'last_name' => 'Smith'],
    [
'first_name' => 'Magic', 'last_name' => 'Johnson']
]

?>
nino at recgr dot com 27-Sep-2016 05:21
array_column implementation that works on multidimensional arrays (not just 2-dimensional):

<?php
function array_column_recursive(array $haystack, $needle) {
   
$found = [];
   
array_walk_recursive($haystack, function($value, $key) use (&$found, $needle) {
        if (
$key == $needle)
           
$found[] = $value;
    });
    return
$found;
}

Taken from https://github.com/NinoSkopac/array_column_recursive
miguelfzarth at gmail dot com 18-Aug-2016 11:02
<?php
# for PHP < 5.5
# AND it works with arrayObject AND array of objects

if (!function_exists('array_column')) {
    function
array_column($array, $columnKey, $indexKey = null)
    {
       
$result = array();
        foreach (
$array as $subArray) {
            if (
is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
               
$result[] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
            } elseif (
array_key_exists($indexKey, $subArray)) {
                if (
is_null($columnKey)) {
                   
$index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                   
$result[$index] = $subArray;
                } elseif (
array_key_exists($columnKey, $subArray)) {
                   
$index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                   
$result[$index] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
                }
            }
        }
        return
$result;
    }
}
?>
greensea 06-Jul-2016 11:42
<?php
if (!function_exists('array_column')) {
    function
array_column($input, $column_key, $index_key = NULL) {
        if (!
is_array($input)) {
           
trigger_error(__FUNCTION__ . '() expects parameter 1 to be array, ' . gettype($input) . ' given', E_USER_WARNING);
            return
FALSE;
        }
       
       
$ret = array();
        foreach (
$input as $k => $v) {       
           
$value = NULL;
            if (
$column_key === NULL) {
               
$value = $v;
            }
            else {
               
$value = $v[$column_key];
            }
           
            if (
$index_key === NULL || !isset($v[$index_key])) {
               
$ret[] = $value;
            }
            else {
               
$ret[$v[$index_key]] = $value;
            }  
        }
       
        return
$ret;
    }
}
?>
benjam 26-Mar-2016 02:20
Note that this function will return the last entry when possible keys are duplicated.

<?php

$array
= array(
    array(
       
'1-1',
       
'one',
       
'one',
    ),
    array(
       
'1-2',
       
'two',
       
'one',
    ),
);

var_dump(array_column($array, $value = 0, $index = 1));
var_dump(array_column($array, $value = 0, $index = 2));

// returns:
/*

array (size=2)
  'one' => string '1-1' (length=3)
  'two' => string '1-2' (length=3)

array (size=1)
  'one' => string '1-2' (length=3)

*/
?>
Nolan chou 27-Feb-2016 02:21
if (!function_exists('array_column'))
{
    function array_column($input, $column_key=null, $index_key=null)
    {
        $result = array();
        $i = 0;
        foreach ($input as $v)
        {
            $k = $index_key === null || !isset($v[$index_key]) ? $i++ : $v[$index_key];
            $result[$k] = $column_key === null ? $v : (isset($v[$column_key]) ? $v[$column_key] : null);
        }
        return $result;
    }
}
Anonymous 13-Feb-2016 01:45
I added a little more functionality to the more popular answers here to support the $index_key parameter for PHP < 5.5

<?php
// for php < 5.5
if (!function_exists('array_column')) {
    function
array_column($input, $column_key, $index_key = null) {
       
$arr = array_map(function($d) use ($column_key, $index_key) {
            if (!isset(
$d[$column_key])) {
                return
null;
            }
            if (
$index_key !== null) {
                return array(
$d[$index_key] => $d[$column_key]);
            }
            return
$d[$column_key];
        },
$input);

        if (
$index_key !== null) {
           
$tmp = array();
            foreach (
$arr as $ar) {
               
$tmp[key($ar)] = current($ar);
            }
           
$arr = $tmp;
        }
        return
$arr;
    }
}
?>
kaspar dot wilbuer at web dot de 01-Feb-2016 07:59
If you need to extract more than one column from an array, you can use array_intersect_key on each element, like so:

function array_column_multi(array $input, array $column_keys) {
    $result = array();
    $column_keys = array_flip($column_keys);
    foreach($input as $key => $el) {
        $result[$key] = array_intersect_key($el, $column_keys);
    }
    return $result;
}
antonfedonjuk at gmail dot com 22-Jul-2015 03:26
My version is closer to the original than http://github.com/ramsey/array_column
<?php
/**
 * Provides functionality for array_column() to projects using PHP earlier than
 * version 5.5.
 * @copyright (c) 2015 WinterSilence (http://github.com/WinterSilence)
 * @license MIT
 */
if (!function_exists('array_column')) {
   
/**
     * Returns an array of values representing a single column from the input
     * array.
     * @param array $array A multi-dimensional array from which to pull a
     *     column of values.
     * @param mixed $columnKey The column of values to return. This value may
     *     be the integer key of the column you wish to retrieve, or it may be
     *     the string key name for an associative array. It may also be NULL to
     *     return complete arrays (useful together with index_key to reindex
     *     the array).
     * @param mixed $indexKey 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.
     * @return array
     */
   
function array_column(array $array, $columnKey, $indexKey = null)
    {
       
$result = array();
        foreach (
$array as $subArray) {
            if (!
is_array($subArray)) {
                continue;
            } elseif (
is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
               
$result[] = $subArray[$columnKey];
            } elseif (
array_key_exists($indexKey, $subArray)) {
                if (
is_null($columnKey)) {
                   
$result[$subArray[$indexKey]] = $subArray;
                } elseif (
array_key_exists($columnKey, $subArray)) {
                   
$result[$subArray[$indexKey]] = $subArray[$columnKey];
                }
            }
        }
        return
$result;
    }
}
?>
till at etill dot net 29-May-2015 12:32
Some remarks not included in the official documentation.

1) array_column does not support 1D arrays, in which case an empty array is returned.

2) The $column_key is zero-based.

3) If $column_key extends the valid index range an empty array is returned.
marianbucur17 at yahoo dot com 18-May-2015 03:19
If array_column is not available you can use the following function, which also has the $index_key parameter:

if (!function_exists('array_column')) {
    function array_column($array, $column_key, $index_key = null)
    {
        return array_reduce($array, function ($result, $item) use ($column_key, $index_key)
        {
            if (null === $index_key) {
                $result[] = $item[$column_key];
            } else {
                $result[$item[$index_key]] = $item[$column_key];
            }

            return $result;
        }, []);
    }
}
mohanrajnr at gmail dot com 06-May-2015 04:50
if array_column does not exist the below solution will work.

if(!function_exists("array_column"))
{

    function array_column($array,$column_name)
    {

        return array_map(function($element) use($column_name){return $element[$column_name];}, $array);

    }

}
robbieaverill[at]gmail.com 24-Mar-2015 04:51
Another option for older PHP versions (pre 5.5.0) is to use array_walk():

<?php
$array
= array(
  array(
'some' => 'var', 'foo' => 'bar'),
  array(
'some' => 'var', 'foo' => 'bar'),
  array(
'some' => 'var', 'foo' => 'bar')
);

array_walk($array, function(&$value, $key, $return) {
 
$value = $value[$return];
},
'foo');

print_r($array);

// Array
// (
//     [0] => bar
//     [1] => bar
//     [2] => bar
// )

?>
kiler129 @ nowhere 10-Jan-2015 11:31
Please note this function accepts 2D-arrays ONLY, and silently returns empty array when non-array argument is provided.

Code:
class testObject {
    public $a = 123;
}
$testArray = [new testObject(), new testObject(), new testObject()];
$result = array_column($testArray, 'a')); //array(0) { }
hypxm at qq dot com 09-Dec-2014 03:36
a simple solution:

function arrayColumn(array $array, $column_key, $index_key=null){
        if(function_exists('array_column ')){
            return array_column($array, $column_key, $index_key);
        }
        $result = [];
        foreach($array as $arr){
            if(!is_array($arr)) continue;

            if(is_null($column_key)){
                $value = $arr;
            }else{
                $value = $arr[$column_key];
            }

            if(!is_null($index_key)){
                $key = $arr[$index_key];
                $result[$key] = $value;
            }else{
                $result[] = $value;
            }

        }

        return $result;
    }
coviex 01-Dec-2014 01:53
Value for existing key in the resulting array is rewritten with new value if it exists in another source sub-array.
myles at smyl dot es 23-Nov-2014 11:52
This didn't work for me recursively and needed to come up with a solution.

Here's my solution to the function:

if ( ! function_exists( 'array_column_recursive' ) ) {
    /**
     * Returns the values recursively from columns of the input array, identified by
     * the $columnKey.
     *
     * Optionally, you may provide an $indexKey to index the values in the returned
     * array by the values from the $indexKey column in the input array.
     *
     * @param array $input     A multi-dimensional array (record set) from which to pull
     *                         a column of values.
     * @param mixed $columnKey The column of values to return. This value may be the
     *                         integer key of the column you wish to retrieve, or it
     *                         may be the string key name for an associative array.
     * @param mixed $indexKey  (Optional.) 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.
     *
     * @return array
     */
    function array_column_recursive( $input = NULL, $columnKey = NULL, $indexKey = NULL ) {

        // Using func_get_args() in order to check for proper number of
        // parameters and trigger errors exactly as the built-in array_column()
        // does in PHP 5.5.
        $argc   = func_num_args();
        $params = func_get_args();
        if ( $argc < 2 ) {
            trigger_error( "array_column_recursive() expects at least 2 parameters, {$argc} given", E_USER_WARNING );

            return NULL;
        }
        if ( ! is_array( $params[ 0 ] ) ) {
            // Because we call back to this function, check if call was made by self to
            // prevent debug/error output for recursiveness :)
            $callers = debug_backtrace();
            if ( $callers[ 1 ][ 'function' ] != 'array_column_recursive' ){
                trigger_error( 'array_column_recursive() expects parameter 1 to be array, ' . gettype( $params[ 0 ] ) . ' given', E_USER_WARNING );
            }

            return NULL;
        }
        if ( ! is_int( $params[ 1 ] )
             && ! is_float( $params[ 1 ] )
             && ! is_string( $params[ 1 ] )
             && $params[ 1 ] !== NULL
             && ! ( is_object( $params[ 1 ] ) && method_exists( $params[ 1 ], '__toString' ) )
        ) {
            trigger_error( 'array_column_recursive(): The column key should be either a string or an integer', E_USER_WARNING );

            return FALSE;
        }
        if ( isset( $params[ 2 ] )
             && ! is_int( $params[ 2 ] )
             && ! is_float( $params[ 2 ] )
             && ! is_string( $params[ 2 ] )
             && ! ( is_object( $params[ 2 ] ) && method_exists( $params[ 2 ], '__toString' ) )
        ) {
            trigger_error( 'array_column_recursive(): The index key should be either a string or an integer', E_USER_WARNING );

            return FALSE;
        }
        $paramsInput     = $params[ 0 ];
        $paramsColumnKey = ( $params[ 1 ] !== NULL ) ? (string) $params[ 1 ] : NULL;
        $paramsIndexKey  = NULL;
        if ( isset( $params[ 2 ] ) ) {
            if ( is_float( $params[ 2 ] ) || is_int( $params[ 2 ] ) ) {
                $paramsIndexKey = (int) $params[ 2 ];
            } else {
                $paramsIndexKey = (string) $params[ 2 ];
            }
        }
        $resultArray = array();
        foreach ( $paramsInput as $row ) {
            $key    = $value = NULL;
            $keySet = $valueSet = FALSE;
            if ( $paramsIndexKey !== NULL && array_key_exists( $paramsIndexKey, $row ) ) {
                $keySet = TRUE;
                $key    = (string) $row[ $paramsIndexKey ];
            }
            if ( $paramsColumnKey === NULL ) {
                $valueSet = TRUE;
                $value    = $row;
            } elseif ( is_array( $row ) && array_key_exists( $paramsColumnKey, $row ) ) {
                $valueSet = TRUE;
                $value    = $row[ $paramsColumnKey ];
            }

            $possibleValue = array_column_recursive( $row, $paramsColumnKey, $paramsIndexKey );
            if ( $possibleValue ) {
                $resultArray = array_merge( $possibleValue, $resultArray );
            }

            if ( $valueSet ) {
                if ( $keySet ) {
                    $resultArray[ $key ] = $value;
                } else {
                    $resultArray[ ] = $value;
                }
            }
        }

        return $resultArray;
    }
}
WARrior 03-Oct-2013 09:25
You can also use array_map fucntion if you haven't array_column().

example:

$a = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    )
);

array_column($a, 'last_name');

becomes

array_map(function($element){return $element['last_name'];}, $a);