5-bo‘lim
Massivlar
PHP massivi - tartiblangan xarita; indeksli va assotsiativ massivlar, saralash, filtrlash va ko'p o'lchovli tuzilmalar.
Ushbu bo‘lim mundarijasi
PHP da massiv - oddiy ro'yxat emas. U tartiblangan xarita: kalit-qiymat juftliklari, lekin qo'shilish tartibini ham saqlaydi.
Aynan shuning uchun PHP da massiv bir vaqtning o'zida ro'yxat, lug'at, stek va navbat vazifasini bajaradi.
Ikki ko'rinish #
// Har bir misol qat'iy turlar rejimida ishlaydi.
// Indeksli - kalitlar 0 dan boshlanadi
$shaharlar = ["Toshkent", "Namangan", "Samarqand"];
// Assotsiativ - kalitlar o'zingiz beradigan satrlar
$aholi = [
"Toshkent" => 2900000,
"Namangan" => 650000,
"Samarqand" => 560000,
];
echo "Indeksli massiv:\n";
foreach ($shaharlar as $kalit => $qiymat) {
echo " [{$kalit}] => {$qiymat}\n";
}
echo "\nAssotsiativ massiv:\n";
foreach ($aholi as $shahar => $son) {
printf(" %-12s %12s\n", $shahar, number_format($son, 0, ",", " "));
}
echo "\n";
echo "Aralash ham mumkin (lekin tavsiya etilmaydi):\n";
$aralash = ["a", "kalit" => "qiymat", "b"];
foreach ($aralash as $k => $v) {
echo " " . var_export($k, true) . " => {$v}\n";
}
Indeksli massiv:
[0] => Toshkent
[1] => Namangan
[2] => Samarqand
Assotsiativ massiv:
Toshkent 2 900 000
Namangan 650 000
Samarqand 560 000
Aralash ham mumkin (lekin tavsiya etilmaydi):
0 => a
'kalit' => qiymat
1 => b
PHP da ["a", "b"] va [0 => "a", 1 => "b"] - bir
xil narsa. Indeksli massiv shunchaki kalitlari butun
son bo'lgan assotsiativ massiv.
Buni tekshirish oson:
var_dump(["a", "b"] === [0 => "a", 1 => "b"]); // true
Bu qulaylik, lekin tuzoq ham: massivdan element o'chirsangiz, kalitlar qayta raqamlanmaydi:
| Amal | Natija kalitlari |
|---|---|
["a","b","c"] | 0, 1, 2 |
unset($m[1]) | 0, 2 |
array_values($m) | 0, 1 |
Agar natijani JSON ga aylantirsangiz, birinchi holat
massiv (["a","c"]), ikkinchisi esa obyekt
({"0":"a","2":"c"}) bo'lib chiqadi.
Shuning uchun: filtrlagandan keyin deyarli har doim
array_values() chaqiring. 18-bo'limda bu xato
qanday API buzishini ko'ramiz.
Qo'shish va o'chirish #
$vazifalar = [];
// Oxiriga qo'shish
$vazifalar[] = "Hisobotni yozish";
$vazifalar[] = "Xatga javob berish";
array_push($vazifalar, "Uchrashuvga tayyorlanish");
// Boshiga qo'shish
array_unshift($vazifalar, "SHOSHILINCH: serverni tekshirish");
echo "Ro'yxat (" . count($vazifalar) . " ta):\n";
foreach ($vazifalar as $i => $v) {
echo " " . ($i + 1) . ". {$v}\n";
}
echo "\n";
$oxirgi = array_pop($vazifalar);
echo "array_pop olib tashladi: {$oxirgi}\n";
$birinchi = array_shift($vazifalar);
echo "array_shift olib tashladi: {$birinchi}\n";
echo "\nQolgan: " . count($vazifalar) . " ta\n";
foreach ($vazifalar as $i => $v) {
echo " [{$i}] {$v}\n";
}
Ro'yxat (4 ta):
1. SHOSHILINCH: serverni tekshirish
2. Hisobotni yozish
3. Xatga javob berish
4. Uchrashuvga tayyorlanish
array_pop olib tashladi: Uchrashuvga tayyorlanish
array_shift olib tashladi: SHOSHILINCH: serverni tekshirish
Qolgan: 2 ta
[0] Hisobotni yozish
[1] Xatga javob berish
Qidirish va tekshirish #
$ruxsatlar = ["o'qish", "yozish", "o'chirish"];
$narxlar = ["non" => 4000, "sut" => 12500, "shakar" => 9800];
printf("%-38s %s\n", "in_array('yozish'):", in_array("yozish", $ruxsatlar, true) ? "ha" : "yo'q");
printf("%-38s %s\n", "in_array('boshqarish'):", in_array("boshqarish", $ruxsatlar, true) ? "ha" : "yo'q");
echo "\n";
printf("%-38s %s\n", "array_key_exists('sut'):", array_key_exists("sut", $narxlar) ? "ha" : "yo'q");
printf("%-38s %s\n", "isset(\$narxlar['sut']):", isset($narxlar["sut"]) ? "ha" : "yo'q");
echo "\n";
$joy = array_search("o'chirish", $ruxsatlar, true);
echo "array_search o'rni: " . var_export($joy, true) . "\n";
$yoq = array_search("boshqarish", $ruxsatlar, true);
echo "Topilmasa qaytaradi: " . var_export($yoq, true) . "\n";
echo "\n";
echo "Kalitlar: " . implode(", ", array_keys($narxlar)) . "\n";
echo "Qiymatlar: " . implode(", ", array_values($narxlar)) . "\n";
echo "12500 ga mos kalit: " . array_search(12500, $narxlar, true) . "\n";
in_array('yozish'): ha
in_array('boshqarish'): yo'q
array_key_exists('sut'): ha
isset($narxlar['sut']): ha
array_search o'rni: 2
Topilmasa qaytaradi: false
Kalitlar: non, sut, shakar
Qiymatlar: 4000, 12500, 9800
12500 ga mos kalit: sut
in_array ni uchinchi argumentsiz chaqirmangin_array($nima, $massiv) standart holatda ==
bilan solishtiradi - ya'ni turlarni aylantiradi.
Bu qanday xavf tug'diradi:
$ruxsat_berilgan = [1, 2, 3];
in_array("1abc", $ruxsat_berilgan); // PHP 7 da TRUE edi
in_array(true, $ruxsat_berilgan); // TRUE - har qanday son bilan
Uchinchi argument true - bu qat'iy solishtirish
(===) degani:
in_array($nima, $massiv, true); // har doim shunday
array_search($nima, $massiv, true); // bu ham
array_keys($massiv, $qiymat, true); // bu ham
Xuddi shu holat array_search uchun ham amal qiladi.
isset va array_key_exists farqi ham muhim:
| Kalit yo'q | Kalit bor, qiymati null | |
|---|---|---|
isset() | false | false |
array_key_exists() | false | true |
Ya'ni isset null qiymatni "yo'q" deb hisoblaydi.
Agar null sizga mazmunli qiymat bo'lsa -
array_key_exists ishlating.
map, filter, reduce #
$mahsulotlar = [
["nom" => "Klaviatura", "narx" => 350000, "soni" => 3],
["nom" => "Sichqoncha", "narx" => 120000, "soni" => 10],
["nom" => "Monitor", "narx" => 2400000, "soni" => 2],
["nom" => "Quloqchin", "narx" => 89000, "soni" => 0],
];
// map - har biriga jami summani qo'shamiz
$hisoblangan = array_map(
static fn(array $m): array => $m + ["jami" => $m["narx"] * $m["soni"]],
$mahsulotlar
);
echo "Barcha mahsulotlar:\n";
foreach ($hisoblangan as $m) {
printf(" %-12s %2d dona %12s\n", $m["nom"], $m["soni"],
number_format($m["jami"], 0, ",", " "));
}
// filter - faqat omborda borlarini qoldiramiz
$mavjud = array_values(array_filter(
$hisoblangan,
static fn(array $m): bool => $m["soni"] > 0
));
echo "\nOmborda bor: " . count($mavjud) . " ta\n";
// reduce - umumiy qiymatni hisoblaymiz
$umumiy = array_reduce(
$mavjud,
static fn(int $yigindi, array $m): int => $yigindi + $m["jami"],
0
);
echo "Ombor qiymati: " . number_format($umumiy, 0, ",", " ") . " so'm\n";
// array_column - bitta ustunni ajratib olish
$nomlar = array_column($mavjud, "nom");
echo "Nomlar: " . implode(", ", $nomlar) . "\n";
// array_column kalit bilan - juda qulay
$narxJadvali = array_column($mahsulotlar, "narx", "nom");
echo "\nNarx jadvali:\n";
foreach ($narxJadvali as $nom => $narx) {
printf(" %-12s %12s\n", $nom, number_format($narx, 0, ",", " "));
}
Barcha mahsulotlar:
Klaviatura 3 dona 1 050 000
Sichqoncha 10 dona 1 200 000
Monitor 2 dona 4 800 000
Quloqchin 0 dona 0
Omborda bor: 3 ta
Ombor qiymati: 7 050 000 so'm
Nomlar: Klaviatura, Sichqoncha, Monitor
Narx jadvali:
Klaviatura 350 000
Sichqoncha 120 000
Monitor 2 400 000
Quloqchin 89 000
array_column - eng kam baholanadigan funksiyaMa'lumotlar bazasidan kelgan natija odatda shunday ko'rinadi:
[
["id" => 1, "nom" => "Ali", "email" => "ali@..."],
["id" => 2, "nom" => "Vali", "email" => "vali@..."],
]
array_column uni bir chaqiruvda kerakli shaklga
keltiradi:
| Chaqiruv | Natija |
|---|---|
array_column($r, "nom") | ["Ali", "Vali"] |
array_column($r, "nom", "id") | [1 => "Ali", 2 => "Vali"] |
array_column($r, null, "id") | [1 => [...], 2 => [...]] |
Uchinchi variant ayniqsa foydali: u butun qatorlarni
id bo'yicha indekslaydi va keyin $foydalanuvchilar[5]
deb to'g'ridan-to'g'ri murojaat qilish mumkin bo'ladi -
tsikl bilan qidirish shart emas.
Obyektlar bilan ham ishlaydi: array_column($obyektlar,
"nom") ochiq xossalarni oladi.
Saralash #
$baholar = ["Malika" => 88, "Husanboy" => 94, "Nodira" => 76, "Aziza" => 94];
$nusxa = $baholar;
arsort($nusxa); // qiymat bo'yicha kamayish, kalit saqlanadi
echo "Ball bo'yicha (yuqoridan):\n";
foreach ($nusxa as $ism => $ball) {
printf(" %-10s %d\n", $ism, $ball);
}
$nusxa = $baholar;
ksort($nusxa); // kalit bo'yicha
echo "\nAlifbo bo'yicha:\n";
echo " " . implode(", ", array_keys($nusxa)) . "\n";
echo "\n";
// usort - o'z qoidangiz bilan, ko'p mezonli saralash
$talabalar = [
["ism" => "Malika", "ball" => 88, "yosh" => 20],
["ism" => "Husanboy", "ball" => 94, "yosh" => 25],
["ism" => "Aziza", "ball" => 94, "yosh" => 22],
["ism" => "Nodira", "ball" => 76, "yosh" => 21],
];
usort($talabalar, static function (array $a, array $b): int {
// Avval ball bo'yicha kamayish tartibida
$farq = $b["ball"] <=> $a["ball"];
// Ball teng bo'lsa - yosh bo'yicha o'sish tartibida
return $farq !== 0 ? $farq : ($a["yosh"] <=> $b["yosh"]);
});
echo "Ko'p mezonli saralash:\n";
foreach ($talabalar as $t) {
printf(" %-10s ball %d, yosh %d\n", $t["ism"], $t["ball"], $t["yosh"]);
}
Ball bo'yicha (yuqoridan):
Husanboy 94
Aziza 94
Malika 88
Nodira 76
Alifbo bo'yicha:
Aziza, Husanboy, Malika, Nodira
Ko'p mezonli saralash:
Aziza ball 94, yosh 22
Husanboy ball 94, yosh 25
Malika ball 88, yosh 20
Nodira ball 76, yosh 21
<=> - kosmik kema operatori$a <=> $b uch qiymatdan birini qaytaradi:
| Holat | Natija |
|---|---|
$a < $b | -1 |
$a === $b | 0 |
$a > $b | 1 |
Bu aynan usort kutgan narsa, shuning uchun
solishtiruvchi funksiyalar juda qisqa yoziladi:
usort($m, fn($a, $b) => $a["narx"] <=> $b["narx"]);
Tartibni teskari qilish uchun argumentlarni
almashtiring: $b["narx"] <=> $a["narx"].
Ko'p mezonli saralashning qisqa shakli ham bor - massivlarni solishtirish:
usort($t, fn($a, $b) =>
[$b["ball"], $a["yosh"]] <=> [$a["ball"], $b["yosh"]]
);
PHP massivlarni element-element solishtiradi, shuning uchun bu ikki mezonni birdan hal qiladi.
Ko'p o'lchovli massivlar #
$guruhlar = [
"KI-21" => [
["ism" => "Malika", "ball" => 88],
["ism" => "Nodira", "ball" => 76],
],
"KI-22" => [
["ism" => "Husanboy", "ball" => 94],
["ism" => "Aziza", "ball" => 91],
["ism" => "Kamola", "ball" => 83],
],
];
foreach ($guruhlar as $guruh => $talabalar) {
$ballar = array_column($talabalar, "ball");
$ortacha = array_sum($ballar) / count($ballar);
printf("%s (%d talaba, o'rtacha %.2f)\n", $guruh, count($talabalar), $ortacha);
foreach ($talabalar as $t) {
printf(" %-10s %d\n", $t["ism"], $t["ball"]);
}
}
echo "\n";
// Barcha talabalarni bitta ro'yxatga yig'ish
$hammasi = array_merge(...array_values($guruhlar));
echo "Jami talabalar: " . count($hammasi) . "\n";
$engYaxshi = array_reduce(
$hammasi,
static fn(?array $eng, array $t): array =>
$eng === null || $t["ball"] > $eng["ball"] ? $t : $eng
);
echo "Eng yuqori ball: {$engYaxshi['ism']} ({$engYaxshi['ball']})\n";
KI-21 (2 talaba, o'rtacha 82.00)
Malika 88
Nodira 76
KI-22 (3 talaba, o'rtacha 89.33)
Husanboy 94
Aziza 91
Kamola 83
Jami talabalar: 5
Eng yuqori ball: Husanboy (94)
- Indeksli va assotsiativ massiv yarating, ikkalasini
foreachbilan chiqaring. ["a","b","c"]danunset($m[1])qiling va kalitlarni ko'ring.array_values()bilan kalitlarni qayta raqamlang.in_arrayni uchinchi argumentsiz vatruebilan solishtiring.issetvaarray_key_existsninullqiymatli kalitda sinang.array_mapbilan har bir narxga soliq qo'shing.array_filterdan keyin JSON ga aylantiring - massivmi yoki obyekt?array_columnbilanidbo'yicha indekslangan jadval yasang.usortva<=>bilan ikki mezon bo'yicha saralang.array_merge(...)bilan ko'p o'lchovli massivni yassilang.
Xulosa #
- PHP massivi - tartiblangan xarita; indeksli massiv shunchaki butun sonli kalitlarga ega.
unset()kalitlarni qayta raqamlamaydi -array_values()chaqiring.- Filtrlangan massivni JSON ga aylantirsangiz, u obyekt bo'lib chiqishi mumkin.
in_array,array_search,array_keysga har doim uchinchi argumenttruebering.isset()nullqiymatni "yo'q" deb hisoblaydi;array_key_exists()esa yo'q.array_map,array_filter,array_reduceyangi massiv qaytaradi - asli o'zgarmaydi.sort,usort,array_pushesa massivni joyida o'zgartiradi.- Saralashda:
a- qiymat bo'yicha,k- kalit bo'yicha,r- teskari. array_columnbazadan kelgan qatorlarni bir chaqiruvda qayta shakllantiradi.<=>operatoriusortuchun ideal; massivlarni solishtirib ko'p mezonni birdan hal qiladi.
Keyingi bo'limda shartlar, sikllar va match ifodasini
ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.