(PHP 5 >= 5.5.0, PHP 7, PHP 8)
array_column — Liefert die Werte einer einzelnen Spalte eines Arrays
$array
, int |string |null $column_key
, int |string |null $index_key
= null
): array
array_column() gibt die Werte einer einzelnen Spalte von
array
zurück, die durch
column_key
angegeben wird. Optional kann ein
index_key
angegeben werden, um die Werte im
zurückgegebenen Array durch die Werte der Spalte
index_key
des angegebenen Arrays zu indizieren.
array
Ein mehrdimensionales Array oder ein Array von Objekten, aus dem eine Spalte von Werten abgerufen werden soll. Wenn ein Array von Objekten angegeben wird, können die öffentlichen Eigenschaften direkt abgerufen werden. Damit geschützte oder private Eigenschaften abgerufen werden können, muss die Klasse die magischen Methoden __get() und __isset() implementieren.
column_key
Die Spalte der zurückzugebenden Werte. Dieser Wert kann ein
Integer-Schlüssel der Spalte sein, die abgerufen werden soll, oder der
Name eines Zeichenketten-Schlüssels eines assoziativen Arrays oder
einer Eigenschaft. Er kann auch null
sein, um komplette Arrays oder
Objekte zurückzugeben (dies ist in Verbindung mit
index_key
nützlich, um das Array neu zu
indizieren).
index_key
Die Spalte, die als Index/Schlüssel für das zurückgegebene Array verwendet werden soll. Dieser Wert kann der Integer-Schlüssel der Spalte sein oder der Name des Zeichenketten-Schlüssels. Der Wert wird konvertiert wie für Array-Schlüssel üblich (vor PHP 8.0.0 waren jedoch auch Objekte erlaubt, die die Konvertierung in eine Zeichenkette unterstützen).
Gibt ein Array von Werten zurück, das eine einzelne Spalte aus dem angegebenen Array enthält.
Version | Beschreibung |
---|---|
8.0.0 |
Die Objekte der Spalten, die durch den Parameter
index_key angegeben werden, werden nicht mehr
in Zeichenketten umgewandelt, sondern lösen stattdessen einen
TypeError aus.
|
Beispiel #1 Auslesen der Spalte der Vornamen aus einem Datensatz
<?php
// Ein Array, das einen Datensatz enthält, wie er von einer Datenbank
// stammen könnte
$records = [
[
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
],
[
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
],
[
'id' => 5342,
'first_name' => 'Jane',
'last_name' => 'Jones',
],
[
'id' => 5623,
'first_name' => 'Peter',
'last_name' => 'Doe',
]
];
$first_names = array_column($records, 'first_name');
print_r($first_names);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [0] => John [1] => Sally [2] => Jane [3] => Peter )
Beispiel #2 Abrufen der Spalte der Nachnamen aus einem Datensatz, indiziert durch die Spalte "id"
<?php
// Verwenden des Arrays $records aus Beispiel #1
$records = [
[
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
],
[
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
],
[
'id' => 5342,
'first_name' => 'Jane',
'last_name' => 'Jones',
],
[
'id' => 5623,
'first_name' => 'Peter',
'last_name' => 'Doe',
]
];
$last_names = array_column($records, 'last_name', 'id');
print_r($last_names);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [2135] => Doe [3245] => Smith [5342] => Jones [5623] => Doe )
Beispiel #3 Abrufen der Spalte mit den Benutzernamen aus der öffentlichen Eigenschaft "username" eines Objekts
<?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'));
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [0] => user 1 [1] => user 2 [2] => user 3 )
Beispiel #4 Abrufen der Spalte der Namen aus der privaten Eigenschaft "name" eines Objekts mit der magischen Methode __get()
<?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'));
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Array ( [0] => Fred [1] => Jane [2] => John )
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);
}
}
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
)
)
?>
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
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']
]
*/
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.
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;
}
?>
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
Array multiple columns:
<?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);
}
?>
EXAMPLE:
<?php
$products = [
[
'id' => 2,
'name' => 'Phone',
'price' => 210.3
],
[
'id' => 3,
'name' => 'Laptop',
'price' => 430.12
]
];
print_r(array_columns($products, 'name', 'price'));
?>
Output:
Array
(
[0] => Array
(
[name] => Phone
[price] => 210.3
)
[1] => Array
(
[name] => Laptop
[price] => 430.12
)
)
<?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;
}
}
?>
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;
}
}
?>
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)
*/
?>
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
)
)
//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;
}
}
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;
}
}
?>
If you want to preserve the array keys AND you want it to work on both object properties and array elements AND you want it to work if some of the arrays/objects in the array do not have the given key/property defined, basically the most ROBUST version you can get, yet quick enough:
<?php
function array_column_keys(array|ArrayAccess $arr, string $col) {
// like array_columns but keeps the keys
//to make it work for objects and arrays
return array_map(fn($e) => (is_countable($e) ? ($e[$col]??null) : null) ?: (is_object($e) ? $e->$col : null), $arr);
}
?>
If a key/property is undefined, the value in the result array will be NULL. You can use array_filter() to filter those out if needed.
<?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');
?>
Returns:
Array
(
[one] => plop
[3] => property a
[4] => something else
[5] =>
[kud] => property a
)
If an entry in the source array does not have a column_key element then array_column will silently skip that entry and return an array shorter than the source.
If entries can't be uniquely identified by an index_key then there's no way of telling which ones were skipped, as without an index_key array_column returns a plain list.
<?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'));
?>
array_column is the only function out of array_values, array_merge, array_slice and array_column that does de-reference values. Also, it works recursive!
<?php
$values = [];
$values['a'] = [];
$values['a']['b'] = 'foo';
$references = [];
$references['a'] = &$values['a'];
$copyColumn = array_combine(array_keys($references), array_column($references, null));
$values['a']['b'] = 'baz';
echo $copyColumn['a']['b'] . PHP_EOL; // foo
echo $references['a']['b'] . PHP_EOL; // baz
?>
If you want to preserve the keys you can use
<?php
$dereferenced = array_combine(array_keys($references), array_column($references, null))
?>
I didn't see this explicitly mentioned in the documentation but if an array value is not an array (or an object with the correct functions for access) or the column_key doesn't exist then that value will simply not have a corresponding value in the output
so array_column([[4,5,6], [7,8,9], 10], 0) will return [4,7]. It also means that the suggestion of
array_combine(array_keys($array), array_column($array, 'column'));
to preserve keys isn't safe unless you verify that nothing will be excluded by the array_column call.
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;
}
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 (!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;
}
}
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 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;
}, []);
}
}
If you want to rearrage an array with two layers (perhaps from database-requests), then use 'array_walk' instead:
<?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");
?>
The Result
===========
...
Output
Array
(
[0] => Array
(
[0] => hallo ich
[1] => ich
)
[1] => Array
(
[0] => hallo du
[1] => du
)
[2] => Array
(
[0] => hallo er
[1] => er
)
)