Notatki PHP

prywatne zapiski na kamieniu

array_column - Zwraca wartości z wybranej kolumny tabeli wejściowej

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

 
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'Jaśko',
        'last_name' => 'Pawlak',
    ),
    array(
        'id' => 3245,
        'first_name' => 'John',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Kaśka',
        'last_name' => 'Pawlaczka',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Jack',
        'last_name' => 'September',
    )
);
 
$first_names = array_column($records, 'first_name');
print_r($first_names);

Otrzymamy z tego przykładu gdzie kluczem wskazanym jest first_name tablicy, nową tablicę zawierającą same imiona:

 
Array ( [0] => Jaśko [1] => John [2] => Kaśka [3] => Jack ) 

 

W tym samym przykładzie, możemy tworzyć nową tablicę dla id oraz nazwisk:

 
$last_names = array_column($records, 'last_name', 'id');
print_r($last_names);

Otrzymamy:

 
Array ( [2135] => Pawlak [3245] => Smith [5342] => Pawlaczka [5623] => September ) 

Jest to całkiem dobry sposób by móc wyeliminować z danej tablicy kolumny w danym momencie niepotrzebne do przetwarzania danych - wystarczy je pominąć w tej funkcji i w ten sposób "zgubić".

 

Wykorzystując programowanie obiektowe, funkcja ta również może być użyteczna:

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

Otrzymamy:

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

 

Kolejny przykład z obiektówką:

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

Otrzymamy

 
Array ( [0] => Fred [1] => Jane [2] => John ) 

 

Inny przykład przetwarzania danych z tabeli gdy funkcja nasza nie jest dostępna w sposób naturalny, czyli piszemy swoją:

 
// Array representing a possible record set returned from a database
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'Jaśko',
        'last_name' => 'Pawlak',
    ),
    array(
        'id' => 3245,
        'first_name' => 'John',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Kaśka',
        'last_name' => 'Pawlaczka',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Jack',
        'last_name' => 'September',
    )
);
 
 
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;
}
 
 
 $c = array_column_recursive($records, 'id');
    var_dump($c);

Sortujemy tabelę wg. kolumny 'id' i otrzymujemy nową tablicę zawierającą same indeksy 'id'.

 
array(4) { [0]=> int(2135) [1]=> int(3245) [2]=> int(5342) [3]=> int(5623) }

 

 

Z tabeli danych usuwamy wybranych użytkowników o podawanych imionach - filtrujemy ich i usuwamy z bazy:

 
 
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'));
 
// Pozostały:
[
    ['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']
]

 

Wydobywamy dwie lub więcej kolumn z tabeli i zapisujemy je do osobnej tablicy:

 
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'Jaśko',
        'last_name' => 'Pawlak',
    ),
    array(
        'id' => 3245,
        'first_name' => 'John',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Kaśka',
        'last_name' => 'Pawlaczka',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Jack',
        'last_name' => 'September',
    )
);
 
 
 
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;
}
 
 
$selected = array ("id", "last_name");
 
   $c = array_column_multi($records, $selected);
    var_dump($c);

Otrzymamy wybrane z indeksów tabeli w tablicy $selected:

 
array (4)
0 => array (2)
 id => 2135
 last_name => "Pawlak" (6)
1 => array (2)
 id => 3245
 last_name => "Smith" (5)
2 => array (2)
 id => 5342
 last_name => "Pawlaczka" (9)
3 => array (2)
 id => 5623
 last_name => "September" (9)

 

Dla starszych wersji PHP <5.5 może okazać się, że nie jest dostępna nasza funkcja, więc trzeba ją utworzyć:

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

Podobnie:

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

 

Tworzymy tablicę, gdzie kluczami i elementami są wybrane elementy z tabeli:

 
 
$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_column($records, 'first_name', 'first_name'));

Otrzymamy:

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

Zamieńmy wybrane dwie kolumny miejscami:

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

Otrzymamy:

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

Problemem jest Sally nr 2, która przy takim przetwarzaniu może nam znikać.