Filtrarea unei colecții
Filtrarea înseamnă alegerea elementelor unei colecții care îndeplinesc o condiție.
Condiția se scrie ca o funcție care primește un element și returnează true (îl păstrăm) sau false (îl sărim). O astfel de funcție se numește predicat.
Filtrarea construiește un tablou nou. Tabloul original nu este modificat.
PHP are un filtru integrat: array_filter(). Primește un tablou și un predicat și returnează un tablou nou cu elementele pentru care predicatul spune da. Sintaxa scurtă a funcției-săgeată fn($w) => ... menține apelul compact.
Un lucru de ținut minte: array_filter() păstrează cheile originale. Când vrei o listă curată, numerotată din nou de la 0, învelește rezultatul în array_values().
Filtrarea după predicat
Cel mai simplu mod de a filtra este să transmiți tabloul și un predicat către array_filter(). În mod implicit, predicatul primește doar valoarea.
Cu indicatorul ARRAY_FILTER_USE_BOTH predicatul primește valoarea și cheia, astfel încât un tablou asociativ poate fi filtrat după ambele în același timp. Indicatorul ARRAY_FILTER_USE_KEY transmite doar cheia.
Într-o listă simplă cheile sunt pozițiile 0, 1, 2, …, deci ARRAY_FILTER_USE_BOTH permite și ca o condiție să folosească indicele elementului.
Pentru a păstra elementele care nu se potrivesc, pune ! în fața condiției. PHP nu are un filterNot separat.
Un tablou PHP poate conține valori de tipuri diferite. is_string() verifică dacă o valoare este un șir de caractere, iar $v !== null sare peste intrările care nu conțin nicio valoare.
Filtrarea unui tablou
Păstrăm doar cuvintele mai lungi de 3 litere. Condiția strlen($w) > 3 este transmisă lui array_filter() ca funcție-săgeată.
array_filter() păstrează cheile originale, așa că cuvintele păstrate se află în continuare la 2 și 3, iar json_encode() afișează {"2":"three","3":"four"}. După array_values() cheile încep din nou de la 0 și același apel afișează lista curată ["three","four"].
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
// array_filter() păstrează fiecare element pentru care predicatul spune da.
$longerThan3 = array_filter($words, fn($w) => strlen($w) > 3);
// Cheile originale supraviețuiesc: "three" și "four" păstrează cheile 2 și 3.
echo json_encode($longerThan3), "\n";
// array_values() renumerotează cheile de la 0, dând o listă curată.
echo json_encode(array_values($longerThan3)), "\n";
Filtrarea unui tablou asociativ
Perechile a căror cheie se termină cu "1" și a căror valoare este mai mare decât 10 sunt păstrate. Indicatorul ARRAY_FILTER_USE_BOTH face ca array_filter() să transmită predicatului atât valoarea, cât și cheia, iar str_ends_with() verifică sfârșitul cheii.
Ieșire: script PHP
<?php
$numbersMap = ["key1" => 1, "key2" => 2, "key3" => 3, "key11" => 11];
// ARRAY_FILTER_USE_BOTH transmite predicatului valoarea și cheia.
$filteredMap = array_filter(
$numbersMap,
fn($value, $key) => str_ends_with($key, "1") && $value > 10,
ARRAY_FILTER_USE_BOTH
);
echo json_encode($filteredMap), "\n";
Filtrarea folosind indicele
În listă, cheia fiecărui cuvânt este poziția lui. Cu ARRAY_FILTER_USE_BOTH predicatul vede cuvântul și indicele lui. Un cuvânt este păstrat doar când indicele lui nu este 0 și are mai puțin de 5 litere.
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
// Într-o listă cheile sunt pozițiile, deci cheia este indicele.
$filteredIdx = array_filter(
$words,
fn($w, $i) => $i !== 0 && strlen($w) < 5,
ARRAY_FILTER_USE_BOTH
);
echo json_encode(array_values($filteredIdx)), "\n";
Filtrarea cu o condiție negată
Eliminăm cuvintele cu 3 litere sau mai puține. Condiția strlen($w) = 3 este negată cu !, așa că rămân doar cuvintele mai lungi.
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
// PHP nu are filterNot: neagă condiția cu ! în interiorul predicatului.
$filteredNot = array_filter($words, fn($w) => !(strlen($w) <= 3));
echo json_encode(array_values($filteredNot)), "\n";
Filtrarea după tip
Tabloul conține null, un număr, două șiruri de caractere și un număr real. Funcția de apel inversat is_string(...) este funcția integrată însăși, transmisă cu sintaxa first-class callable. Fiecare șir de caractere păstrat este afișat cu majuscule.
Ieșire: script PHP
<?php
$mixed = [null, 1, "two", 3.5, "four"];
// is_string(...) transmite ca predicat funcția integrată însăși.
$strings = array_filter($mixed, is_string(...));
foreach ($strings as $s) {
echo strtoupper($s), "\n";
}
Eliminarea valorilor null
Tabloul conține șiruri de caractere și intrări null. Testul explicit $v !== null păstrează valorile reale. Nu apela array_filter() fără o funcție de apel inversat aici: ar elimina orice valoare „falsy”, inclusiv 0, "" și chiar șirul de caractere "0".
Ieșire: script PHP
<?php
$nullableList = [null, "one", null, "two"];
// Testează tu însuți față de null: fără o funcție de apel inversat, array_filter()
// ar elimina și orice altă valoare „falsy”, cum ar fi 0, "" și "0".
$values = array_filter($nullableList, fn($v) => $v !== null);
echo json_encode(array_values($values)), "\n";
Partiționarea
Uneori vrei ambele grupuri: elementele care se potrivesc și cele care nu se potrivesc.
PHP nu are un partition integrat. O singură buclă foreach face acest lucru: fiecare element este adăugat cu []= fie în tabloul $match, fie în tabloul $rest. După buclă ai ambele tablouri.
Împărțirea unui tablou în două
Cuvintele mai lungi de 3 litere ajung în $match; toate celelalte ajung în $rest. Ambele tablouri sunt afișate.
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
$match = [];
$rest = [];
foreach ($words as $w) {
if (strlen($w) > 3) {
$match[] = $w;
} else {
$rest[] = $w;
}
}
echo json_encode($match), "\n";
echo json_encode($rest), "\n";
Testarea predicatelor
Uneori nu ai nevoie de elementele care se potrivesc, ci doar de un răspuns da sau nu.
- any: trece cel puțin un element testul?
array_any(), nou în PHP 8.4, răspunde la această întrebare și se oprește la prima potrivire. - none: nu trece niciun element testul? Pune
!în fața luiarray_any(). - all: trece fiecare element testul?
array_all(), de asemenea nou în PHP 8.4, răspunde la această întrebare.
Fără o condiție, „există vreun element?” este count($arr) > 0, iar „nu există niciun element?” este count($arr) === 0.
Pe un tablou gol, array_all() returnează true. Nu există niciun element care să nu treacă testul, deci testul nu este niciodată încălcat. Acest lucru se numește adevăr vid.
Exemplele afișează răspunsurile cu json_encode(), care transformă valorile booleene în textul lizibil true și false.
any
Verificăm dacă cel puțin un cuvânt se termină cu "e", apoi verificăm dacă tabloul are vreun element. array_any() se oprește imediat ce "one" trece testul — celelalte cuvinte nu sunt testate.
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
// array_any() este true dacă cel puțin un element trece testul.
$anyE = array_any($words, fn($w) => str_ends_with($w, "e"));
echo json_encode($anyE), "\n";
// „există vreun element?” este doar o verificare a numărului de elemente.
echo json_encode(count($words) > 0), "\n";
none
Verificăm că niciun cuvânt nu se termină cu "a", apoi verificăm dacă tabloul este gol. array_any() nu găsește nimic și returnează false, așa că ! transformă rezultatul în true.
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
// „none” este opusul lui „any”: niciun element nu trece testul.
$noneA = !array_any($words, fn($w) => str_ends_with($w, "a"));
echo json_encode($noneA), "\n";
// „nu există niciun element?” este doar o verificare a numărului de elemente.
echo json_encode(count($words) === 0), "\n";
all
Verificăm dacă fiecare cuvânt se termină cu "e". array_all() se oprește la "two" și returnează false. Pe un tablou gol returnează true.
Ieșire: script PHP
<?php
$words = ["one", "two", "three", "four"];
// array_all() este true doar când fiecare element trece testul.
echo json_encode(array_all($words, fn($w) => str_ends_with($w, "e"))), "\n";
// Un tablou gol nu are niciun element care să nu treacă testul, deci array_all() este true.
echo json_encode(array_all([], fn($w) => str_ends_with($w, "e"))), "\n";