PHP Conference Japan 2024

array_column

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

array_column返回输入数组中单个列的值

描述

array_column(数组 $array, 整数|字符串| $column_key, 整数|字符串| $index_key = ): 数组

array_column() 返回 array 中单个列的值,该列由 column_key 标识。可选地,可以提供 index_key,以根据输入数组的 index_key 列中的值对返回数组中的值进行索引。

参数

array

一个多维数组或一个对象数组,从中提取一列值。如果提供了对象数组,则可以直接提取公共属性。为了提取受保护或私有属性,该类必须同时实现 __get()__isset() 魔术方法。

column_key

要返回的值的列。此值可以是您希望检索的列的整数键,也可以是关联数组或属性名称的字符串键名。它也可以是 以返回完整的数组或对象(这与 index_key 一起使用以重新索引数组非常有用)。

index_key

用作返回数组的索引/键的列。此值可以是列的整数键,也可以是字符串键名。该值像往常一样被 强制转换 为数组键(但是,在 PHP 8.0.0 之前,也允许支持转换为字符串的对象)。

返回值

返回一个值数组,表示输入数组中的一列。

变更日志

版本 描述
8.0.0 index_key 参数指示的列中的对象将不再强制转换为字符串,现在将抛出 TypeError 异常。

示例

示例 #1 从记录集中获取姓名的列

<?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 获取记录集中姓氏的列,并以“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”属性获取用户名列

<?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() 方法从对象的私有“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
)
如果未提供 __isset(),则将返回一个空数组。

添加注释

用户贡献的注释 25 条注释

mohanrajnr at gmail dot com
9 年前
如果不存在 array_column,以下解决方案将起作用。

if(!function_exists("array_column"))
{

function array_column($array,$column_name)
{

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

}

}
WARrior
11 年前
如果您没有 array_column(),也可以使用 array_map 函数。

示例

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

变为

array_map(function($element){return $element['last_name'];}, $a);
balbuf
6 年前
此函数不会保留数组的原始键(当不提供 index_key 时)。

您可以这样解决

<?php
// 不是
array_column($array, 'column');

// 保留键
array_combine(array_keys($array), array_column($array, 'column'));
?>
yangmeishu at live dot com
4 年前
请注意,如果您使用 array_column 重置索引,当索引值为 null 时,在不同的 PHP 版本中会有不同的结果,示例
<?php

$array
= [
[
'name' =>'Bob',
'house' =>'big',
],
[
'name' =>'Alice',
'house' =>'small',
],
[
'name' =>'Jack',
'house' => null,
],
];
var_dump(array_column($array,null,'house'));

在 5.6.307.0.07.2.0 (不限于)上获得以下结果
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
}
}

新索引null 将被转换为 int,并且可以根据之前的索引递增,也就是说如果 Alice "house" 也是 null那么 Alice's 新索引是 "0", Jack's 索引是 "1"

在 7.1.217.2.187.4.8 (不限于)上将获得以下结果
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
}
}

新索引 null 将被转换为一个空字符串
till at etill dot net
9 年前
官方文档中未包含的一些说明。

1) array_column 不支持一维数组,在这种情况下会返回一个空数组。

2) $column_key 是从 0 开始的。

3) 如果 $column_key 超出有效索引范围,则会返回一个空数组。
opencart dot ocfilter at gmail dot com
1 年前
数组多列

<?php
function array_columns() {
$args = func_get_args();

$array = array_shift($args);

if (!
$args) {
return
$array;
}

$keys = array_flip($args);

return
array_map(function($element) use($keys) {
return
array_intersect_key($element, $keys);
},
$array);
}
?>
示例
<?php
$products
= [
[
'id' => 2,
'name' => 'Phone',
'price' => 210.3
],
[
'id' => 3,
'name' => 'Laptop',
'price' => 430.12
]
];

print_r(array_columns($products, 'name', 'price'));
?>

输出

数组
(
[0] => 数组
(
[name] => Phone
[price] => 210.3
)

[1] => 数组
(
[name] => Laptop
[price] => 430.12
)

)
nino at recgr dot com
8 年前
适用于多维数组(不仅仅是二维)的 array_column 实现

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

取自 https://github.com/NinoSkopac/array_column_recursive
ff2 AT hotmail DOT co DOT uk
6 年前
由于我的 PHP 版本中没有此函数,所以我编写了自己的版本,并根据我的需求对其进行了扩展。

当您为 `$indexkey` 赋值 -1 时,它会保留关联数组的键值。

示例

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

输出

数组
(
[0] => 10
[1] => 20
[2] => 30
)

print_r(array_column_ext($sample,'val1',-1));

输出

数组
(
['test1'] => 10
['test2'] => 20
['test3'] => 30
)

print_r(array_column_ext($sample,'val1','val2'));

输出

数组
(
[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;
}
?>
Sbastien
2 年前
`array_column()` 的对应函数,即从列创建数组,可以使用 `array_map()` 来实现。

<?php

// 列
$lastnames = ['Skywalker', 'Organa', 'Kenobi'];
$firstnames = ['Luke', 'Leia', 'Obiwan'];

// 将列转换为数组
$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']
]
*/
miguelfzarth at gmail dot com
8 年前
<?php
# 适用于 PHP < 5.5
# 并且适用于 ArrayObject 和对象数组

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;
}
}
?>
Carlos Granados
8 年前
这是一个用于根据列值过滤记录集的小片段。



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

// 用法:

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

// 输出:
[
[
'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']
]

?>
匿名用户
8 年前
我为这里更受欢迎的答案添加了一些额外的功能,以支持 PHP < 5.5 的 `$index_key` 参数。

<?php
// 适用于 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;
}
}
?>
benjam
8 年前
请注意,当可能的键重复时,此函数将返回最后一个条目。

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

// 返回:
/*

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

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

*/
?>
1184427175 at qq dot com
7 年前
//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;
}
}
antonfedonjuk at gmail dot com
9 年前
我的版本比 http://github.com/ramsey/array_column 更接近原始版本。
<?php
/**
* 为 PHP 5.5 之前的版本提供 array_column() 的功能。
* @copyright (c) 2015 WinterSilence (http://github.com/WinterSilence)
* @license MIT
*/
if (!function_exists('array_column')) {
/**
* 返回一个数组,该数组的值表示输入数组中的一列。
* @param array $array 一个多维数组,从中提取一列值。
* @param mixed $columnKey 要返回的值所在的列。此值可以是您想要检索的列的整数键,也可以是关联数组的字符串键名。它也可以是 NULL 以返回完整的数组(与 index_key 一起使用以重新索引数组)。
* @param mixed $indexKey 用作返回数组的索引/键的列。此值可以是列的整数键,也可以是字符串键名。
* @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;
}
}
?>
Rumour
1 年前
如果您想保留数组键,并且希望它同时适用于对象属性和数组元素,并且希望它在数组中的一些数组/对象未定义给定的键/属性时也能工作,基本上是您可以获得的最稳健的版本,但速度也足够快。

<?php
function array_column_keys(array|ArrayAccess $arr, string $col) {
// 类似 array_columns 但保留键
// 使其适用于对象和数组

return array_map(fn($e) => (is_countable($e) ? ($e[$col]??null) : null) ?: (is_object($e) ? $e->$col : null), $arr);
}

?>

如果键/属性未定义,则结果数组中的值为 NULL。如果需要,可以使用 array_filter() 过滤掉它们。

<?php

class a {
public
string $a = 'property a';
public
string $b = 'property b';
}

$a1 = new a;
$a2 = new a;
$a2->a = 'plop';

$b = ['one'=> ['a'=>'plop'],
3 => $a1,
4 => $a2,
5 =>[],
'kud'=>new a];

return
array_column_keys($b, 'a');

?>

返回值

数组
(
[one] => plop
[3] => property a
[4] => 其他值
[5] =>
[kud] => property a
)
oleg dot bolden at gmail dot com
2 年前
索引键仅在对应索引的值在整个数组中唯一时才能安全地应用。否则,只有具有相同索引键值的数组的最后一个元素会被提取。

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

以上示例将输出

<?php
Array
(
[
1] => Jane
[2] => Peter
)
?>

要对数组中具有相同`index_key`的值进行分组,可以使用如下示例函数对`array_column`进行简单的替换

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

输出结果

<?php
Array
(
[
1] => Array
(
[
0] => John
[1] => Sally
[2] => Jane
)
[
2] => Array
(
[
0] =>Peter
)
)
?>
Hayley Watson
6 个月前
如果源数组中的条目没有 column_key 元素,则 array_column 会静默跳过该条目并返回一个比源数组短的数组。

如果条目无法通过 index_key 唯一标识,则无法确定哪些条目被跳过,因为如果没有 index_key,array_column 会返回一个普通列表。

<?php
$array
= [
[
'a' => '0th', 'b' => 'zero'],
[
'a' => '1st', 'b' => 'one'],
[
'a' => '2nd' /* oops */],
[
'a' => '3rd', 'b'=>'three']];
var_export(array_column($array, 'b'));
var_export(array_column($array, 'b', 'a'));
?>
Hiranmoy Chatterjee
2 年前
以下函数可能有助于从索引数组的所有值创建列

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

使用方法
-----
<?php
array_column_all
(
[
[
'A1', 'A2', 'A3'],
[
'B1', 'B2', 'B3'],
[
'C1', 'C2', 'C3'],
]
);
?>

输出结果
-------------------
数组
(
[0] => 数组
(
[0] => A1
[1] => B1
[2] => C1
)

[1] => 数组
(
[0] => A2
[1] => B2
[2] => C2
)

[2] => 数组
(
[0] => A3
[1] => B3
[2] => C3
)

)
Nolan chou
8 年前
如果 (!function_exists('array_column'))
{
函数 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;
}
}
hypxm at qq dot com
9 年前
一个简单的解决方案

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;
}
kaspar dot wilbuer at web dot de
8 年前
如果您需要从数组中提取多个列,您可以对每个元素使用 array_intersect_key,如下所示

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;
}
katrinaelaine6 at gmail dot com
7 年前
array_column() 将返回重复的值。

无需使用 array_unique(),只需将 $index_key 作为一种技巧。

**注意:当将 $column_key 和/或 $index_key 设置为整数时,这可能会变得很混乱。**

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

// 强制唯一性,使键成为值。
print_r(array_column($records, 'first_name', 'first_name'));
print_r(array_column($records, 'id', 'first_name'));

// 返回
/*

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

数组
(
[John] => John
[Sally] => Sally
[Jane] => Jane
[Peter] => Peter
)

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

*/

?>
marianbucur17 at yahoo dot com
9 年前
如果 array_column 不可使用,您可以使用以下函数,该函数也具有 $index_key 参数

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;
}, []);
}
}
info at mobger dot de
1 年前
如果要重新排列一个有两层(可能是来自数据库请求)的数组,则使用“array_walk”代替

<?php

$yamlList
= [
[
'title' => 'hallo ich', 'identifier' => 'ich', 'Klaus'=> 'doof',],
[
'title' => 'hallo du', 'identifier' => 'du', 'Klaus'=> 'doof',],
[
'title' => 'hallo er', 'identifier' => 'er', 'Klaus'=> 'doof',],
];
echo (
'Input'."\n".print_r($yamlList,true)."\n");
array_walk($yamlList, function (&$value, $key) {
$value = [
$value['title'],
$value['identifier'],
];
});
echo (
"\n".'Output'."\n".print_r($yamlList,true)."\n");
?>

结果
===========
...
输出
数组
(
[0] => 数组
(
[0] => hallo ich
[1] => ich
)

[1] => 数组
(
[0] => hallo du
[1] => du
)

[2] => 数组
(
[0] => hallo er
[1] => er
)

)
To Top