WisarWisar
Dasturlash kitobi/2-QISM — JavaScript14 daqiqa

2.7-bob: Array va barcha metodlari (map, filter, reduce, find, ...)

2-QISM — JavaScript (0 dan chuqurgacha) · 7-mavzu


1. Kirish va motivatsiya

Bu — JavaScript'ning eng ko'p ishlatiladigan bobi. Real dasturda ma'lumot deyarli doim ro'yxat (massiv) ko'rinishida keladi: mahsulotlar, foydalanuvchilar, xabarlar, izohlar. Ularni o'zgartirish, filtrlash, yig'ish, qidirish — kunlik ish. Va buni for tsikli 2.2-bob bilan emas, Array metodlari bilan qilamiz — qisqaroq, o'qishliroq, xatosizroq.

.map, .filter, .reduce — bularni mukammal bilish — JS dasturchi bo'lishning majburiy sharti. React (11) butunlay shularga tayanadi: har bir ro'yxat render — .map. Backend (5) — ma'lumotni .filter/.reduce bilan qayta ishlaydi.

O'xshatish: massiv — konveyer lentasidagi qutilar. map — har qutiga yorliq yopishtiradi (har birini o'zgartiradi). filter — faqat keraklisini o'tkazadi (saralovchi). reduce — hammasini bitta qutiga jamlaydi (yig'uvchi). Bu uch "ishchi" — ma'lumot qayta ishlashning yuragi.

Bu bob — 2.2 (tsikllar) ning zamonaviy, deklarativ shakli va funksional dasturlashning 2.15-bob amaliy poydevori.


2. Nazariya — chuqur tushuntirish

2.1. Massiv nima va asoslar

Massiv (array) — tartibli qiymatlar ro'yxati (2.1: obyekt turi). Har elementning indeksi bor (0 dan — 0.1):

js
const mevalar = ["olma", "nok", "uzum"];
mevalar.length;     // 3
mevalar[0];         // "olma"
mevalar[2];         // "uzum"
mevalar[mevalar.length - 1]; // "uzum" (oxirgi)

2.2. ENG MUHIM tushuncha: mutating vs non-mutating

Array metodlari ikki turga bo'linadi:

  • Mutating (o'zgartiruvchi) — asl massivni o'zgartiradi: push, pop, shift, unshift, splice, sort, reverse.
  • Non-mutating (o'zgartirmaydigan) — asl massivga tegmaydi, yangi massiv/qiymat qaytaradi: map, filter, slice, concat, reduce, find.

Bu — eng muhim farq. Zamonaviy JS (ayniqsa React — 11) immutability (o'zgartirmaslik) ni afzal ko'radi: asl massivni buzmang, yangi yarating. Mutating metodlar yashirin bug'lar manbai. Shuning uchun map/filter (non-mutating) ni push ichidagi tsikldan afzal ko'ring.

2.3. Element qo'shish/olib tashlash (mutating)

js
const arr = [1, 2, 3];

arr.push(4);        // oxiriga qo'shadi  [1,2,3,4]; yangi uzunlikni qaytaradi
arr.pop();          // oxirgini olib tashlaydi  [1,2,3]; olinganni qaytaradi
arr.unshift(0);     // boshiga qo'shadi  [0,1,2,3]
arr.shift();        // boshidagini oladi  [1,2,3]

// splice(boshlanish, nechta, ...yangilar) — eng kuchli (o'zgartiradi!)
arr.splice(1, 1);          // 1-indeksdan 1 ta o'chir  [1,3]
arr.splice(1, 0, "yangi"); // 1-indeksga qo'sh (o'chirmasdan)  [1,"yangi",3]

2.4. map — har elementni o'zgartirish (eng muhim)

map — har element ustida funksiyani bajarib, natijalardan yangi massiv qaytaradi (transformatsiya — MDN). Asl massiv o'zgarmaydi:

js
const sonlar = [1, 2, 3, 4];

const ikkilangan = sonlar.map(n => n * 2);   // [2, 4, 6, 8]
const kvadratlar = sonlar.map(n => n ** 2);  // [1, 4, 9, 16]

// Obyekt massividan biror maydonni olish (juda ko'p ishlatiladi)
const userlar = [{ ism: "Ali" }, { ism: "Vali" }];
const ismlar = userlar.map(u => u.ism);      // ["Ali", "Vali"]

map — React'ning yuragi (11): ro'yxatni JSX'ga aylantirish doim .map bilan. Yodlab qoling: map = har elementni o'zgartirib, yangi massiv.

2.5. filter — saralash

filter — shartni (true qaytaruvchi) qanoatlantiradigan elementlardan yangi massiv. Hajmi teng yoki kichikroq:

js
const sonlar = [1, 2, 3, 4, 5, 6];

const juftlar = sonlar.filter(n => n % 2 === 0);   // [2, 4, 6]
const kattalar = sonlar.filter(n => n > 3);        // [4, 5, 6]

// Obyektlarni filtrlash
const userlar = [{ ism: "Ali", faol: true }, { ism: "Vali", faol: false }];
const faollar = userlar.filter(u => u.faol);       // [{ism:"Ali",...}]

2.6. reduce — bitta qiymatga jamlash

reduce — butun massivni bitta qiymatga (son, obyekt, massiv) jamlaydi. Eng kuchli, lekin boshida qiyinroq:

js
const sonlar = [1, 2, 3, 4];

// Yig'indi: (akkumulyator, joriy) => yangi akkumulyator; 0 — boshlang'ich
const jami = sonlar.reduce((acc, n) => acc + n, 0);   // 10
//                          │     │              │
//                       to'plangan joriy     boshlang'ich qiymat

const kopaytma = sonlar.reduce((acc, n) => acc * n, 1);  // 24

// Obyektga jamlash (sanash)
const harflar = ["a", "b", "a", "c", "a"];
const sanoq = harflar.reduce((acc, h) => {
  acc[h] = (acc[h] || 0) + 1;    // har harfni sanaydi
  return acc;
}, {});                          // {a: 3, b: 1, c: 1}

reduce mentaliteti: "boshlang'ich qiymatdan boshlab, har elementni unga qo'shib boraman". Yig'indi, ko'paytma, sanash, guruhlash — hammasi reduce bilan.

2.7. Qidirish metodlari

js
const sonlar = [4, 8, 15, 16, 23];

sonlar.find(n => n > 10);       // 16 — birinchi MOS QIYMAT (yo'q bo'lsa undefined)
sonlar.findIndex(n => n > 10);  // 3  — birinchi mos INDEKS (yo'q bo'lsa -1)
sonlar.includes(15);            // true — qiymat bormi?
sonlar.indexOf(15);             // 2 — indeksi (yo'q bo'lsa -1)
sonlar.some(n => n > 20);       // true — KAMIDA BITTA mos keladimi?
sonlar.every(n => n > 0);       // true — HAMMASI mos keladimi?
Metod Qaytaradi
find birinchi mos qiymat (yoki undefined)
findIndex birinchi mos indeks (yoki -1)
some kamida bittasi mos boolean
every hammasi mos boolean
includes qiymat bormi boolean

2.8. forEach — har element bo'yicha (side effect)

forEach — har element ustida funksiya; undefined qaytaradi (natija yo'q — faqat side effect: log, DOM — MDN):

js
const ismlar = ["Ali", "Vali"];
ismlar.forEach(ism => console.log(ism));   // har birini chiqaradi
// forEach natija qaytarMAYDI — yangi massiv kerak bo'lsa map ishlat!

forEach vs map: mapyangi massiv (transformatsiya); forEachnatija yo'q (faqat ish bajarish). Yangi massiv kerak bo'lsa — map.

2.9. Tartiblash va ag'darish (mutating!)

js
const sonlar = [3, 1, 4, 1, 5];

// sort — ASL MASSIVNI o'zgartiradi! 2.2-bob Sukut: MATN sifatida saralaydi!
sonlar.sort();              // [1, 1, 3, 4, 5] (bu holda to'g'ri, lekin...)
[10, 2, 1].sort();         // [1, 10, 2] (!!) — matn sifatida (0.1)

//  Son uchun komparator BER:
sonlar.sort((a, b) => a - b);   // o'sish tartibida [1,1,3,4,5]
sonlar.sort((a, b) => b - a);   // kamayish tartibida [5,4,3,1,1]

sonlar.reverse();          // ag'daradi (o'zgartiradi!)

sort ikki tuzog'i: (1) asl massivni o'zgartiradi (nusxa kerak bo'lsa [...arr].sort()); (2) sukut bo'yicha qiymatlarni matn sifatida saralaydi (10 < 2!). Sonlar uchun **doim komparator** (a,b) => a-b.

2.10. Birlashtirish, kesish, tekislash

js
const a = [1, 2], b = [3, 4];

a.concat(b);          // [1,2,3,4] — birlashtirish (non-mutating)
[...a, ...b];         // [1,2,3,4] — spread bilan (2.8 — afzal)
a.slice(0, 1);        // [1] — nusxa (non-mutating, 2.6-string'ga o'xshash)
a.join("-");          // "1-2" — matnga (2.6: split teskarisi)
[[1,2],[3,4]].flat(); // [1,2,3,4] — bir daraja tekislash
[1, 2].flatMap(n => [n, n * 10]); // [1,10,2,20] — map + flat(1) birga (non-mutating)

a.at(-1);             // 2 — oxirgi element (manfiy indeks! arr[arr.length-1] o'rniga)
a.at(0);              // 1 — birinchi (a[0] bilan bir xil)

Array.from("abc");    // ["a","b","c"] — iterable'dan massiv (2.1)
Array.from({ length: 3 }, (_, i) => i); // [0,1,2] — generator (ikkinchi arg = map)
Array.of(7);          // [7] — bitta sonli massiv (Array(7) — 7 ta bo'sh joy! farqi)
Array.isArray(a);     // true — massivmi? (typeof yetmaydi — 2.1)

[0, 0, 0].fill(5);    // [5,5,5] — hammasini to'ldiradi (mutating! 2.2)
new Array(3).fill(0); // [0,0,0] — n ta bir xil qiymatli massiv yasash

2.11. Metodlarni zanjirlash (chaining) — kuchli naqsh

Non-mutating metodlar yangi massiv qaytargani uchun, ularni zanjirlash mumkin (har biri keyingisiga beradi):

js
const userlar = [
  { ism: "Ali", yosh: 25, faol: true },
  { ism: "Vali", yosh: 17, faol: true },
  { ism: "Guli", yosh: 30, faol: false },
];

const natija = userlar
  .filter(u => u.faol)           // faqat faollar (2.5)
  .filter(u => u.yosh >= 18)     // voyaga yetganlar
  .map(u => u.ism)               // faqat ismlar (2.4)
  .join(", ");                   // matnga (2.10)
console.log(natija);             // "Ali"

Bu — funksional dasturlashning 2.15-bob go'zalligi: har qadam toza, o'qishli, mustaqil.


3. Sintaksis — tez ma'lumotnoma

js
// O'zgartiruvchi (mutating) — EHTIYOT BO'L
arr.push(x)  arr.pop()  arr.shift()  arr.unshift(x)
arr.splice(i, n, ...yangi)  arr.sort(cmp)  arr.reverse()  arr.fill(x)

// O'zgartirmaydigan (yangi qaytaradi) — AFZAL
arr.map(fn)  arr.filter(fn)  arr.reduce(fn, init)
arr.find(fn)  arr.findIndex(fn)  arr.some(fn)  arr.every(fn)
arr.slice(a, b)  arr.concat(b)  arr.join(sep)  arr.flat()  arr.flatMap(fn)
arr.includes(x)  arr.indexOf(x)  arr.at(i)  // at: manfiy indeks (-1 = oxirgi)
arr.forEach(fn)  // natija yo'q (side effect)
Array.isArray(x)  Array.from(iter)  Array.of(x)

4. Batafsil kod namunalari

Misol 1 — map/filter/reduce birga (savat hisobi)

js
const savat = [
  { nom: "Non", narx: 3000, soni: 2 },
  { nom: "Sut", narx: 8000, soni: 1 },
  { nom: "Olma", narx: 12000, soni: 3 },
];

// Har mahsulot jami summasi (map — 2.4)
const summalar = savat.map(m => m.narx * m.soni);  // [6000, 8000, 36000]

// Umumiy jami (reduce — 2.6)
const jami = savat.reduce((acc, m) => acc + m.narx * m.soni, 0);  // 50000

// Qimmat mahsulotlar (filter — 2.5)
const qimmatlar = savat.filter(m => m.narx >= 8000).map(m => m.nom);
console.log(qimmatlar);   // ["Sut", "Olma"]
console.log(`Jami: ${jami.toLocaleString("uz")} so'm`);  // 2.6

Misol 2 — Qidirish va tekshirish (2.7)

js
const userlar = [
  { id: 1, ism: "Ali", admin: false },
  { id: 2, ism: "Vali", admin: true },
];

const admin = userlar.find(u => u.admin);          // {id:2, ism:"Vali",...}
const adminBormi = userlar.some(u => u.admin);      // true
const hammaAdminmi = userlar.every(u => u.admin);   // false
const idx = userlar.findIndex(u => u.id === 2);     // 1

Misol 3 — Immutable yangilash (React uslubi — 2.2)

js
const royxat = [1, 2, 3];

//  Qo'shish — yangi massiv (spread — 2.8), push EMAS
const qoshilgan = [...royxat, 4];        // [1,2,3,4] (asl o'zgarmadi)

//  O'chirish — filter bilan
const ochirilgan = royxat.filter(n => n !== 2);  // [1,3]

//  Yangilash — map bilan
const userlar = [{ id: 1, faol: false }];
const yangilangan = userlar.map(u =>
  u.id === 1 ? { ...u, faol: true } : u    // faqat mosini o'zgartir (2.8)
);

Misol 4 — Zanjirlash va guruhlash (2.6, 2.11)

js
const talabalar = [
  { ism: "Ali", baho: 85 },
  { ism: "Vali", baho: 45 },
  { ism: "Guli", baho: 92 },
  { ism: "Hasan", baho: 70 },
];

// O'tganlar, baho bo'yicha tartiblangan ismlar
const otganlar = talabalar
  .filter(t => t.baho >= 50)              // o'tganlar (2.5)
  .sort((a, b) => b.baho - a.baho)        // baho kamayishi (2.9 — komparator!)
  .map(t => `${t.ism} (${t.baho})`);      // formatlash (2.4)
console.log(otganlar);   // ["Guli (92)", "Ali (85)", "Hasan (70)"]

// reduce bilan guruhlash (o'tgan/yiqilgan)
const guruh = talabalar.reduce((acc, t) => {
  const kalit = t.baho >= 50 ? "otgan" : "yiqilgan";
  (acc[kalit] ||= []).push(t.ism);   // guruhga qo'sh
  return acc;
}, {});
console.log(guruh);  // {otgan: ["Ali","Guli","Hasan"], yiqilgan: ["Vali"]}

5. To'g'ri va noto'g'ri holatlar

1) for tsikli o'rniga Array metodlari

js
//  imperativ, ko'p kod
const ikki = [];
for (let i = 0; i < arr.length; i++) ikki.push(arr[i] * 2);

//  deklarativ, o'qishli (2.4)
const ikki = arr.map(n => n * 2);

2) Asl massivni o'zgartirib qo'yish (mutating)

js
//  sort/reverse/push asl massivni buzadi (2.2, 2.9)
const tartibli = arr.sort();   // arr ham o'zgardi!

//  avval nusxa (immutability — 2.2)
const tartibli = [...arr].sort((a, b) => a - b);

3) sortda komparatorsiz sonlar

js
//  matn sifatida saralaydi (2.9)
[10, 2, 1].sort();        // [1, 10, 2]

//  komparator
[10, 2, 1].sort((a, b) => a - b);   // [1, 2, 10]

4) Yangi massiv kerak bo'lganda forEach

js
//  forEach natija qaytarmaydi (2.8)
const ikki = arr.forEach(n => n * 2);   // undefined!

//  map
const ikki = arr.map(n => n * 2);

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — map/filter natijasi undefined elementlar

js
arr.map(n => { n * 2; });   // [undefined, ...] — return yo'q! (2.3)

Sababi: {} blok ishlatib, return unutildi. Yechimi: bitta ifoda bo'lsa {}siz (n => n * 2); blok bo'lsa return.

Xato 2 — Asl massiv kutilmaganda o'zgargan

Sababi: mutating metod (sort/splice/push) 2.2-bob. Yechimi: nusxa oling ([...arr] yoki arr.slice()), keyin o'zgartiring.

Xato 3 — reduce boshlang'ich qiymatsiz

js
[].reduce((a, b) => a + b);   //  TypeError (bo'sh massiv, init yo'q)

Sababi: init qiymat berilmadi 2.6-bob. Yechimi: doim init bering: .reduce((a, b) => a + b, 0).

Xato 4 — find undefined qaytaradi, keyin xato

js
const u = arr.find(x => x.id === 99);   // undefined (topilmadi)
u.ism;   //  Cannot read properties of undefined

Sababi: topilmasa find undefined 2.7-bob. Yechimi: u?.ism 2.1-bob yoki avval tekshiring.

Xato 5 — Array.isArray o'rniga typeof

js
typeof [] === "object"   // true — massivni aniqlamaydi! (2.1)

Sababi: typeof massivni "object" deydi 2.1-bob. Yechimi: Array.isArray(x) 2.10-bob.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • React (11): ro'yxat render — .map (har bir komponent); state immutability — map/filter/spread.
  • Funksional dasturlash 2.15-bob: map/filter/reduce, immutability, pure function.
  • String 2.6-bob: split massiv metodlar join.
  • Object/spread 2.8-bob: immutable yangilash ({...u} — Misol 3).
  • Backend (5, 6): DB natijalarini qayta ishlash; aggregation 6.3-bob.
  • TanStack Query / Redux (12): ma'lumotni transformatsiya.
  • Algoritmlar (3): massiv algoritmlari shu metodlar ustida.

8. Eng yaxshi amaliyotlar (best practices)

  • for o'rniga map/filter/reduce — deklarativ, o'qishli (2.4–2.6).
  • Immutability: asl massivni o'zgartirmang; yangi yarating (map/filter/spread — 2.2, Misol 3).
  • Mutating'dan oldin nusxa ([...arr]/slice) — ayniqsa sort/reverse 2.9-bob.
  • sortga doim komparator sonlar uchun ((a,b)=>a-b — 2.9).
  • Yangi massiv map; faqat ish forEach 2.8-bob.
  • reducega doim boshlang'ich qiymat (6-bo'lim).
  • find natijasini ?. bilan (topilmasa undefined — 6-bo'lim).
  • Zanjirlang (filter().map().sort()) — toza pipeline 2.11-bob, lekin juda uzun bo'lsa bo'lib tashlang.
  • Array.isArray bilan tekshiring (typeof emas — 2.1).

9. Amaliy loyiha: "Ma'lumot Tahlil Quroli (Data Pipeline)"

Array metodlarini to'liq ishlatadigan ma'lumot qayta ishlash loyihasi.

Maqsad

map/filter/reduce/sort va zanjirlashni amalda qo'llab, real ma'lumot to'plamini tahlil qiluvchi funksiyalar yozish; immutability tamoyiliga rioya qilish.

Talablar (requirements)

Berilgan mahsulotlar/foydalanuvchilar massivi (kamida 8 element, har biri obyekt) ustida:

  1. Transformatsiya (map): har mahsulotning jami narxini (narx * soni) hisoblab yangi massiv.
  2. Filtrlash (filter): ma'lum shart bo'yicha (masalan mavjud, narx oralig'i) saralang.
  3. Jamlash (reduce): umumiy summa, o'rtacha narx, eng qimmat/arzon.
  4. Guruhlash (reduce): kategoriya bo'yicha guruhlang ({elektronika: [...], kitob: [...]} — Misol 4).
  5. Qidirish: find (id bo'yicha), some (biror shart bormi), every (hammasi mos).
  6. Tartiblash (sort): narx/baho bo'yicha (komparator bilan, nusxa ustida — 2.9).
  7. Zanjir (pipeline): filtersortmapjoin bilan "hisobot matni" yasang 2.11-bob.
  8. Immutability: hech bir asl massiv o'zgarmasin (qo'shish/o'chirish/yangilash — spread/filter/map bilan — Misol 3).
  9. (Bonus) reduce bilan kategoriya bo'yicha jami summa ({elektronika: 500000, ...}).

Maslahatlar (hint)

  • O'rtacha: jami / massiv.length (bo'sh massivni tekshiring — 0.6).
  • Eng qimmat: reduce bilan yoki Math.max(...arr.map(...)) (2.6, 2.8).
  • Guruhlash: reduceda (acc[kalit] ||= []).push(...) (Misol 4).
  • sort asl massivni buzmaslik uchun [...arr].sort(...) 2.9-bob.
  • Immutable yangilash: arr.map(x => x.id === id ? {...x, ...yangi} : x) (Misol 3, 2.8).

"Tayyor" mezonlari (acceptance criteria)

  • map, filter, reduce, find, some/every, sort — hammasi ishlatilgan.
  • Guruhlash reduce bilan to'g'ri ishlaydi.
  • sort komparator bilan va nusxa ustida (asl o'zgarmaydi).
  • Kamida bitta uzun zanjir (pipeline) bor.
  • Hech bir asl massiv mutatsiyaga uchramaydi (immutability).
  • find natijasi xavfsiz ishlatilgan (?.).
  • reduceda boshlang'ich qiymat bor.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda JS'ning eng ko'p ishlatiladigan vositasini — Array metodlarini o'rgandik:

  • Mutating (push/pop/splice/sort/reverse — asl massivni o'zgartiradi) vs non-mutating (map/filter/slice/reduceyangi qaytaradi). Immutability ni afzal ko'ring.
  • map — har elementni o'zgartirib yangi massiv (React yuragi); filter — saralash; reducebitta qiymatga jamlash (yig'indi, guruhlash).
  • Qidirish: find/findIndex/some/every/includes; forEach — natija yo'q (side effect).
  • sort — komparator bering ((a,b)=>a-b) va nusxa ustida ishlang. Zanjirlash — toza pipeline 2.11-bob.

Keyingi bob — 2.8-bob: Object — yaratish, manipulyatsiya, destructuring, spread/rest. Massivlarni o'zlashtirdik; endi obyektlar — JS'ning ikkinchi asosiy ma'lumot tuzilmasi — ni chuqur ko'ramiz. Destructuring va spread/rest (...) — bu bobda ko'p ishlatdik; keyingi bobda ularni to'liq, chuqur o'rganamiz (React va zamonaviy JS'ning ajralmas qismi).


Foydalanilgan rasmiy/ishonchli manbalar

  • MDN Web Docs — Array (barcha metodlar), Array.prototype.map/filter/reduce
  • MDN Web Docs — mutating vs non-mutating metodlar, sort, find
  • MDN Web Docs — Array.isArray, Array.from, iterator protokoli

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
2.7-bob: Array va barcha metodlari (map, filter, reduce, find, ...) — Wisar