Massiv metodlari — map, filter, reduce
Muammodan boshlaylik
Onlayn do'kon yozyapsiz. Mahsulotlar ro'yxati bor:
const mahsulotlar = [
{ nomi: "Noutbuk", narx: 8_000_000 },
{ nomi: "Telefon", narx: 3_500_000 },
{ nomi: "Quloqlik", narx: 450_000 },
{ nomi: "Sichqon", narx: 180_000 },
];
Uchta vazifa:
- Barcha narxlarga 10% chegirma qo'llash
- Faqat 1 million so'mdan qimmat mahsulotlarni ko'rsatish
- Jami savdo summasini hisoblash
for sikli bilan:
// Vazifa 1
const chegirmali = [];
for (let i = 0; i < mahsulotlar.length; i++) {
chegirmali.push({ ...mahsulotlar[i], narx: mahsulotlar[i].narx * 0.9 });
}
// Vazifa 2
const qimmat = [];
for (let i = 0; i < mahsulotlar.length; i++) {
if (mahsulotlar[i].narx > 1_000_000) {
qimmat.push(mahsulotlar[i]);
}
}
// Vazifa 3
let jami = 0;
for (let i = 0; i < mahsulotlar.length; i++) {
jami += mahsulotlar[i].narx;
}
Ishlaydi. Lekin har bir vazifa uchun alohida massiv, alohida push, alohida sikllar. map, filter, reduce bu uchta vazifani aniq va qisqa yozish uchun yaratilgan.
map — har bir elementni o'zgartirish
map — massivning har bir elementini funksiyadan o'tkazadi va yangi massiv qaytaradi. Asl massiv o'zgarmaydi.
Hayotiy o'xshatma
Zavod konveyer tasmasi. Har bir mahsulot tasma bo'ylab o'tadi, har biriga bir xil operatsiya bajariladi (bo'yash, etiketlash, qadoqlash). Natijada yangi, o'zgartirilgan mahsulotlar chiqadi — asllar saqlanib qoladi.
const narxlar = [1000, 2000, 3000];
const chegirmali = narxlar.map(narx => narx * 0.9);
console.log(chegirmali); // [900, 1800, 2700]
console.log(narxlar); // [1000, 2000, 3000] — o'zgarmadi ✅
Asl masalamizga qaytaylik:
const chegirmali = mahsulotlar.map(m => ({
...m,
narx: m.narx * 0.9,
}));
console.log(chegirmali);
// [
// { nomi: "Noutbuk", narx: 7_200_000 },
// { nomi: "Telefon", narx: 3_150_000 },
// { nomi: "Quloqlik", narx: 405_000 },
// { nomi: "Sichqon", narx: 162_000 },
// ]
map ning qoidalari:
- Har doim asl massiv bilan teng uzunlikda yangi massiv qaytaradi
- Asl massivni o'zgartirmaydi
- Har bir element uchun funksiya qaytarish qiymati yangi massivga yoziladi
filter — shartga mos elementlarni saqlash
filter — har bir element uchun shart tekshiradi. Shart true bo'lsa — saqlanadi. false bo'lsa — tushib qoladi. Yangi massiv qaytaradi.
Hayotiy o'xshatma
Chegara nazorati. Har bir yo'lovchi tekshiriladi — hujjati to'g'ri bo'lsa o'tadi, bo'lmasa o'tmaydi. Asl ro'yxat o'zgarmaydi, faqat o'tganlar yangi ro'yxatga yoziladi.
const sonlar = [1, 2, 3, 4, 5, 6, 7, 8];
const juftlar = sonlar.filter(son => son % 2 === 0);
console.log(juftlar); // [2, 4, 6, 8]
console.log(sonlar); // [1, 2, 3, 4, 5, 6, 7, 8] — o'zgarmadi ✅
Asl masalamiz — 1 million dan qimmat mahsulotlar:
const qimmatlar = mahsulotlar.filter(m => m.narx > 1_000_000);
console.log(qimmatlar);
// [
// { nomi: "Noutbuk", narx: 8_000_000 },
// { nomi: "Telefon", narx: 3_500_000 },
// ]
filter ning qoidalari:
- Yangi massiv asl massivdan kichik yoki teng uzunlikda bo'ladi
- Funksiya
true/falseqaytarishi kerak (yoki truthy/falsy) - Asl massivni o'zgartirmaydi
reduce — massivni bitta qiymatga yig'ish
reduce — massivning barcha elementlarini "yig'ib" bitta natija chiqaradi. Bu natija son, matn, ob'ekt yoki massiv bo'lishi mumkin.
Hayotiy o'xshatma
Kassa apparati. Har bir mahsulot skanerdan o'tadi, oldingi yig'indiga qo'shiladi. Oxirida — bitta yakuniy summa.
reduce(funksiya, boshlangich_qiymat)
Funksiya ikki argument oladi:
accumulator— to'plangan qiymat (oldingi natija)currentValue— hozirgi element
const narxlar = [1000, 2000, 3000, 4000];
const jami = narxlar.reduce((yigindi, narx) => yigindi + narx, 0);
// ↑ ↑ ↑
// yig'ilayotgan hozirgi element boshlang'ich qiymat
console.log(jami); // 10000
Qadam-baqadam nima bo'layotgani:
Boshlang'ich: yigindi = 0
Qadam 1: yigindi = 0 + 1000 = 1000
Qadam 2: yigindi = 1000 + 2000 = 3000
Qadam 3: yigindi = 3000 + 3000 = 6000
Qadam 4: yigindi = 6000 + 4000 = 10000
Natija: 10000
Asl masalamiz — jami savdo summasi:
const jami = mahsulotlar.reduce((sum, m) => sum + m.narx, 0);
console.log(jami); // 12_130_000
reduce faqat son uchun emas. Ob'ekt yaratish:
const mahsulotlar = ["Noutbuk", "Telefon", "Noutbuk", "Quloqlik", "Telefon", "Telefon"];
const soni = mahsulotlar.reduce((hisob, mahsulot) => {
hisob[mahsulot] = (hisob[mahsulot] || 0) + 1; // ← bor bo'lsa oshir, yo'q bo'lsa 0+1
return hisob;
}, {});
console.log(soni);
// { Noutbuk: 2, Telefon: 3, Quloqlik: 1 }
Zanjirli ishlatish
map, filter, reduce birga ishlatilganda kuchli:
// 1 million dan qimmat mahsulotlarga chegirma qo'llab, jami summani hisoblash
const jami = mahsulotlar
.filter(m => m.narx > 1_000_000) // ← faqat qimmatlar
.map(m => m.narx * 0.9) // ← chegirma
.reduce((sum, narx) => sum + narx, 0); // ← jami
console.log(jami); // 10_350_000
Xuddi shu narsa for sikli bilan yozilsa — 10+ qator, alohida massivlar, push lar.
Tez-tez uchraydigan xatolar
map da return unutish:
const sonlar = [1, 2, 3];
// ❌ — return yo'q, har element undefined bo'ladi
const ikkilangan = sonlar.map(son => {
son * 2;
});
console.log(ikkilangan); // [undefined, undefined, undefined]
// ✅ — return bor
const ikkilangan = sonlar.map(son => {
return son * 2;
});
// ✅ — qisqa yozuv (arrow function da qavslar bo'lmasa, return bilvosita)
const ikkilangan = sonlar.map(son => son * 2);
reduce da boshlang'ich qiymat bermaslik:
const sonlar = [1, 2, 3];
// Boshlang'ich qiymat berilmasa — birinchi element accumulator bo'ladi
const jami = sonlar.reduce((sum, son) => sum + son);
console.log(jami); // 6 — bu holda ishlaydi
// Lekin bo'sh massivda — xato!
const bosh = [];
bosh.reduce((sum, son) => sum + son); // ❌ TypeError: Reduce of empty array with no initial value
// ✅ Har doim boshlang'ich qiymat bering
bosh.reduce((sum, son) => sum + son, 0); // 0
map o'rniga forEach ishlatish:
const sonlar = [1, 2, 3];
// ❌ forEach — undefined qaytaradi, natijani saqlab bo'lmaydi
const ikkilangan = sonlar.forEach(son => son * 2);
console.log(ikkilangan); // undefined
// ✅ Yangi massiv kerak bo'lsa — map
const ikkilangan = sonlar.map(son => son * 2);
forEach — faqat yon ta'sir uchun (console.log, DOM yangilash). Yangi massiv kerak bo'lsa — map.
filter + map ni birlashtirish mumkin bo'lsa ham ikki marta aylanish:
const sonlar = [1, 2, 3, 4, 5, 6];
// ❌ Ikki marta aylanadi
const natija = sonlar
.filter(n => n % 2 === 0)
.map(n => n * 10);
// Bu holda muammo yo'q — massiv kichik
// Lekin katta massivlarda reduce bilan birlashtirish mumkin:
const natija = sonlar.reduce((arr, n) => {
if (n % 2 === 0) arr.push(n * 10);
return arr;
}, []);
console.log(natija); // [20, 40, 60]
Amalda kichik massivlarda filter + map o'qishga qulay — shu holda ishlatavering. Faqat juda katta massivlarda birlashtirishni ko'ring.
Xulosa
| Metod | Nima qiladi | Qaytaradi | Uzunlik |
|---|---|---|---|
map |
har elementni o'zgartiradi | yangi massiv | teng |
filter |
shartga moslarni saqlaydi | yangi massiv | kichik yoki teng |
reduce |
barini bitta qiymatga yig'adi | istalgan tur | — |
Uchtasi ham asl massivni o'zgartirmaydi — yangi qiymat qaytaradi.
Zanjir: filter → map → reduce — birinchi tanlang, keyin o'zgartiring, keyin yig'ing.
Keyingi dars
24-dars: Massiv metodlari — find, findIndex, some, every, flat, flatMap