Ćwiczenie, w którym poznajemy czym jest funkcja array_column oraz jak na inne sposoby osiągnąć podobne działanie.

Celem poniższego ćwiczenia będzie zamiana – na różne sposoby – tablicy-listy zawierającej tablice asocjacyjne na prostą tablicę zawierającą określoną kolumnę. Brzmi jak „masło maślane” więc chodzi o to, aby poniższą tablicę records zamienić na tablicę zawierającą imię każdego rekordu, i nic więcej:

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

Zrobimy to sobie na kilka sposobów.

Pętla i wrzucenie do nowej tablicy

Tworzymy nową tablicę. Przechodzimy w pętli po każdym rekordzie i wrzucamy do nowej wartość „first_name”:

$names = [];
foreach($records as $record){
    $names[] = $record["first_name"];
}
print_r($names);
//Array ( [0] => John [1] => Sally [2] => Jane [3] => Peter )

Oczywiście możemy użyć innej pętli, albo innego zapisu, aby osiągnąć to samo:

$names = [];
foreach($records as $record){
    array_push($names, $record["first_name"]);
}
print_r($names);
//Array ( [0] => John [1] => Sally [2] => Jane [3] => Peter )

Mechanizm polega na przejściu po rekordach w pętli i wrzuceniu do nowej tablicy wartości first_name każdego rekordu.

Reduce z pustą tablicą jako akumulatorem

Jeszcze raz – mamy taką tablicę:

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

Chcemy tablicę z wartościami 'first_name’. Możemy, choć to przesadnie skomplikowane podejście moim zdaniem, skorzystać z reduce.

$names = array_reduce($records, function($acc, $record) {
    $acc[] = $record['first_name'];
    return $acc;
}, array());
print_r($names);
//Array ( [0] => John [1] => Sally [2] => Jane [3] => Peter )

Tutaj jako akumulator początkowy (trzeci argument) podaliśmy pustą tablicę. Funkcja callback w reduce zaś zawsze przyjmuje akumulator i rekord i zwraca akumulator.

I u nas też zwraca – wcześniej dodając do niego wartość 'first_name’ każdego rekordu.

Mechanizm jest prosty – weź pustą tablicę jako akumulator i na każdym elemencie rekords wykonaj funkcję, która zwraca akumulator. To on zostanie na końcu zwrócony.

Obiecuję, że następne podejścia będą już tylko prostsze.

Array_map i array_colum

Kolejny sposób to użycie funkcji array_map. Oto przykład jak ona działa na tablicach:

<?php
function cube($n)
{
    return ($n * $n * $n);
}

$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);
?>

Jak widać, array_map robi tablicę na podstawie innej tablicy. Przyjmuje funkcję, która bierze element i coś z nim robi, zwraca go w określonej postaci.

Ta funkcja jest wywoływana na każdym elemencie i w ten sposób otrzymujemy nową tablicę. Na przykład taką, w której liczby zostaną podniesione do sześcianu, jak w przykładzie powyżej.

Możemy naprawdę łatwo zastosować tę logikę, aby wyciągnąć z tablicy 'records’ nasze imiona. Nasza tablica:

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

Nasz map:

$names = array_map(function($person){
    return $person['first_name'];
}, $records);
print_r($names);
//Array ( [0] => John [1] => Sally [2] => Jane [3] => Peter )

Jak widać ta funkcja jest wywoływana na każdym rekordzie. Bierze rekord – zwraca jego „first_name”. I tak na każdym elemencie, aż uzyskamy tablicę imion.

Proste, ale PHP do takich zabaw ma akurat własną, wbudowaną, takim działaniom dedykowaną funkcję – array_column:

$first_names = array_column($records, 'first_name');
print_r($first_names);
// ( [0] => John [1] => Sally [2] => Jane [3] => Peter )

Tak to działa – weź records, wyciągnij z nich wartość 'first_name’ i taką listę mi zwróć. Całą logikę robi za nas PHP.