array_column
(PHP 5 >= 5.5.0, PHP 7, PHP 8)
array_column — 返回输入数组中指定列的值
说明
$array
, int|string|null $column_key
, int|string|null $index_key
= null
): array
array_column() 返回
array
中键名为
column_key
的一列值。 如果指定了可选参数
index_key
,则使用输入数组中
index_key
列的值将作为返回数组中对应值的键。
参数
-
array
-
多维数组或对象数组,从中提取一列值。 如果提供的是对象数组,只有 public 的属性会被直接取出。 如果想取出 private 和 protected 的属性,类必须实现 __get() 和 __isset() 魔术方法。
-
column_key
-
需要返回值的列。它可以是索引数组的列索引,或者是关联数组的列的键,也可以是属性名。 也可以是
null
,此时将返回整个数组(配合index_key
参数来重新索引数组时非常好用)。 -
index_key
-
作为返回数组的索引/键的列。它可以是该列的整数索引,或者字符串键值。 该值会像数组键一样被 强制转换 (但是,在 PHP 8.0.0 之前,也被允许支持转换为字符串对象)。
返回值
返回输入数组中单列值的数组。
范例
示例 #1 从结果集中取出 first_name 列
<?php
// 表示从数据库返回的记录集的数组
$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 )
示例 #2 从结果集中总取出 last_name 列,用相应的“id”作为键值
<?php
// 使用示例 #1 中的 $records 数组
$last_names = array_column($records, 'last_name', 'id');
print_r($last_names);
?>
以上例程会输出:
Array ( [2135] => Doe [3245] => Smith [5342] => Jones [5623] => Doe )
示例 #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 )
示例 #4 通过 __get() 魔术方法从对象中获取 private 属性的 "name" 列。
<?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 )

User Contributed Notes 28 notes
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);
}
}
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);
This function does not preserve the original keys of the array (when not providing an index_key).
You can work around that like so:
<?php
// instead of
array_column($array, 'column');
// to preserve keys
array_combine(array_keys($array), array_column($array, 'column'));
?>
Please note that if you use array_column to reset the index, when the index value is null, there will be different results in different PHP versions, examples
<?php
$array = [
[
'name' =>'Bob',
'house' =>'big',
],
[
'name' =>'Alice',
'house' =>'small',
],
[
'name' =>'Jack',
'house' => null,
],
];
var_dump(array_column($array,null,'house'));
On 5.6.30, 7.0.0, 7.2.0 (not limited to) get the following results
array(3) {
["big"]=>
array(2) {
["name"]=>
string(3) "Bob"
["house"]=>
string(3) "big"
}
["small"]=>
array(2) {
["name"]=>
string(5) "Alice"
["house"]=>
string(5) "small"
}
[0]=>
array(2) {
["name"]=>
string(4) "Jack"
["house"]=>
NULL
}
}
The new index, null will be converted to int, and can be incremented according to the previous index, that is, if Alice "house" is also null, then Alice's new index is "0", Jack's new index is "1"
On 7.1.21, 7.2.18, 7.4.8 (not limited to) will get the following results
array(3) {
["Big"]=>
array(2) {
["name"]=>
string(3) "Bob"
["house"]=>
string(3) "Big"
}
["small"]=>
array(2) {
["name"]=>
string(5) "Alice"
["house"]=>
string(5) "small"
}
[""]=>
array(2) {
["name"]=>
string(4) "Jack"
["house"]=>
NULL
}
}
The new index null will be converted to an empty string
Because the function was not available in my version of PHP, I wrote my own version and extended it a little based on my needs.
When you give an $indexkey value of -1 it preserves the associated array key values.
EXAMPLE:
$sample = array(
'test1' => array(
'val1' = 10,
'val2' = 100
),
'test2' => array(
'val1' = 20,
'val2' = 200
),
'test3' => array(
'val1' = 30,
'val2' = 300
)
);
print_r(array_column_ext($sample,'val1'));
OUTPUT:
Array
(
[0] => 10
[1] => 20
[2] => 30
)
print_r(array_column_ext($sample,'val1',-1));
OUTPUT:
Array
(
['test1'] => 10
['test2'] => 20
['test3'] => 30
)
print_r(array_column_ext($sample,'val1','val2'));
OUTPUT:
Array
(
[100] => 10
[200] => 20
[300] => 30
)
<?php
function array_column_ext($array, $columnkey, $indexkey = null) {
$result = array();
foreach ($array as $subarray => $value) {
if (array_key_exists($columnkey,$value)) { $val = $array[$subarray][$columnkey]; }
else if ($columnkey === null) { $val = $value; }
else { continue; }
if ($indexkey === null) { $result[] = $val; }
elseif ($indexkey == -1 || array_key_exists($indexkey,$value)) {
$result[($indexkey == -1)?$subarray:$array[$subarray][$indexkey]] = $val;
}
}
return $result;
}
?>
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.
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
<?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;
}
}
?>
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;
}
}
?>
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']
]
?>
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;
}
}
?>
The following function may be useful to create columns from all values of indexed arrays:
<?php
function array_column_all(array $arrays): array
{
$output = [];
$columnCount = count($arrays[0]);
for ($i = 0; $i < $columnCount; $i++)
{
$output [] = array_column($arrays, $i);
}
return $output;
}
?>
Use:
-----
<?php
array_column_all(
[
['A1', 'A2', 'A3'],
['B1', 'B2', 'B3'],
['C1', 'C2', 'C3'],
]
);
?>
This will output:
-------------------
Array
(
[0] => Array
(
[0] => A1
[1] => B1
[2] => C1
)
[1] => Array
(
[0] => A2
[1] => B2
[2] => C2
)
[2] => Array
(
[0] => A3
[1] => B3
[2] => C3
)
)
Index_key is safely applicable only in cases when corresponding values of this index are unique through over the array. Otherwise only the latest element of the array with the same index_key value will be picked up.
<?php
$records = array(
array(
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
'company_id' => 1,
),
array(
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
'company_id' => 1,
),
array(
'id' => 5342,
'first_name' => 'Jane',
'last_name' => 'Jones',
'company_id' => 1,
),
array(
'id' => 5623,
'first_name' => 'Peter',
'last_name' => 'Doe',
'company_id' => 2,
)
);
$first_names = array_column($records, 'first_name', 'company_id');
print_r($first_names);
?>
The above example will output:
<?php
Array
(
[1] => Jane
[2] => Peter
)
?>
To group values by the same `index_key` in arrays one can use simple replacement for the `array_column` like below example function:
<?php
function arrayed_column(array $array, int|string $column_key, int|string $index_key) {
$output = [];
foreach ($array as $item) {
$output[$item['index_key']][] = $item['column_key'];
}
return $output;
}
$first_names = arrayed_column($records, 'first_name', 'company_id');
print_r($first_names);
?>
The output:
<?php
Array
(
[1] => Array
(
[0] => John
[1] => Sally
[2] => Jane
)
[2] => Array
(
[0] =>Peter
)
)
?>
The counterpart of array_column(), namely create an array from columns, can be done with array_map() :
<?php
// Columns
$lastnames = ['Skywalker', 'Organa', 'Kenobi'];
$firstnames = ['Luke', 'Leia', 'Obiwan'];
// Columns to array
$characters = array_map(
fn ($l, $f) => ['lastname' => $l, 'firstname' => $f],
$lastnames, $firstnames
);
print_r($characters);
/*
[
0 => ['lastname' => 'Skywalker', 'firstname' => 'Luke']
1 => ['lastname' => 'Organa', 'firstname' => 'Leia']
2 => ['lastname' => 'Kenobi', 'firstname' => 'Obiwan']
]
*/
//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;
}
}
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)
*/
?>
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
)
*/
?>
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;
}
}
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;
}
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) { }
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;
}
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;
}, []);
}
}
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
// )
?>
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;
}
}
<?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;
}
}
?>
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);
Value for existing key in the resulting array is rewritten with new value if it exists in another source sub-array.
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;
}
备份地址:http://www.lvesu.com/blog/php/function.array-column.php