Yuqori tartibli funksiyalar: map, filter va reduce misollarda
Asoslar4 daqInnovialabs tahririyati
Qisqacha
Yuqori tartibli funksiya boshqa funksiyani qabul qiladi yoki qaytaradi; map har bir elementni o‘zgartiradi, filter tekshiruvdan o‘tganlarini qoldiradi, reduce esa to‘plamni bitta qiymatga yig‘adi.
Qisqa javob
Yuqori tartibli funksiya (higher-order function) — boshqa funksiyani argument sifatida qabul qiladigan yoki uni qaytaradigan funksiya. Eng ko‘p ishlatiladigan uchtasi to‘plamlar bilan ishlaydi:
map— har bir elementga funksiyani qo‘llaydi va xuddi shu uzunlikdagi yangi to‘plam qaytaradi.filter— faqat funksiya true qaytargan elementlarni qoldiradi.reduce— barcha elementlarni bitta qiymatga birlashtiradi: yig‘indi, obyekt, maksimum.
Ular odatiy sikllarni qanday aylanib chiqishni emas, nima olish kerakligini qisqa tasvirlash bilan almashtiradi.
Funksiyalar — bu qiymatlar
JavaScript va Python da funksiya oddiy qiymat. Uni o‘zgaruvchiga saqlash, boshqa funksiyaga uzatish va qaytarish mumkin.
const double = (x) => x * 2;
const apply = (fn, value) => fn(value);
apply(double, 5); // 10
def double(x):
return x * 2
def apply(fn, value):
return fn(value)
apply(double, 5) # 10
map, filter va reduce aynan shunday funksiyalar: sikl ichiga qurilgan, siz esa faqat qadamni uzatasiz.
Sikldan map, filter, reduce ga
Vazifa: buyurtmalar ro‘yxatidan to‘langanlarini olib, umumiy summani hisoblash.
Sikl bilan:
let total = 0;
for (const order of orders) {
if (order.paid) {
total += order.amount;
}
}
Yuqori tartibli funksiyalar bilan:
const total = orders
.filter((o) => o.paid)
.map((o) => o.amount)
.reduce((sum, a) => sum + a, 0);
Python da xuddi shu:
from functools import reduce
paid = filter(lambda o: o["paid"], orders)
amounts = map(lambda o: o["amount"], paid)
total = reduce(lambda s, a: s + a, amounts, 0)
Idiomatik Python da odatda comprehension lar va o‘rnatilgan funksiyalar afzal ko‘riladi:
total = sum(o["amount"] for o in orders if o["paid"])
E’tibor bering: Python 3 da map va filter ro‘yxat emas, dangasa iteratorlar qaytaradi. Natija qayta kerak bo‘lsa, uni list() ga o‘rang.
reduce qanday ishlaydi
reduce ikki argumentli funksiyani — akkumulyator va joriy element — hamda boshlang‘ich qiymatni qabul qiladi.
const counts = ["a", "b", "a"].reduce((acc, letter) => {
acc[letter] = (acc[letter] ?? 0) + 1;
return acc;
}, {});
// { a: 2, b: 1 }
Boshlang‘ich qiymatni doim uzating. Busiz JavaScript birinchi elementni boshlang‘ich deb oladi va bo‘sh massivda TypeError beradi.
Zanjirlar
Zanjir retsept kabi yuqoridan pastga o‘qiladi: filtrlash, o‘zgartirish, yig‘ish. Bir nechta amaliy qoida:
- Imkon bo‘lsa, filter ni map dan oldin qo‘ying — kamroq elementni o‘zgartirasiz.
- Callback larni toza saqlang: yon ta’sirlarsiz va tashqi o‘zgaruvchilarni o‘zgartirmasdan. Shunda har bir qadamni alohida test qilish oson.
- Murakkab callback larga nom bering:
.filter(isActiveUser)uch qatorli strelkali funksiyadan yaxshiroq o‘qiladi. - JavaScript da massiv zanjirining har bir qadami yangi oraliq massiv yaratishini yodda tuting. Oddiy interfeys ma’lumotlari uchun bu normal; issiq koddagi juda katta hajmlar uchun — o‘lchang.
O‘qilish chegaralari
Yuqori tartibli funksiyalar kodni avtomatik ravishda o‘qiladigan qilmaydi. Xavotirli belgilar:
- Bir necha qatordan uzun, tarmoqlanish va ichma-ich obyektlarga ega
reducecallback i. - Besh va undan ko‘p qadamli zanjirlar, ularda qadamlar orasidagi ma’lumot shakli izohsiz tushunarsiz.
mapni faqat yon ta’sirlar uchun ishlatish (log yozish, so‘rov yuborish) — buning uchunforEachyoki sikl bor.
Oddiy sikl qachon yaxshiroq
| Vaziyat | Yaxshiroq tanlov |
|---|---|
Erta to‘xtash kerak (break) | sikl yoki find / some / every |
Ketma-ket, birin-ketin await chaqiruvlari | await bilan for...of |
| Bir nechta yig‘uvchili murakkab holat | sikl |
| Ulkan massivlardagi tezlik muhim kod | o‘lchovlardan keyin sikl |
| Oddiy o‘zgartirish, filtr yoki yig‘indi | map / filter / reduce |
forEach, map va reduce asinxron callback larni navbat bilan kutmaydi. async funksiyali map promise lar massivini qaytaradi — aynan parallel bajarish kerak bo‘lsa, uni Promise.all ga uzatish mumkin.
Ko‘p uchraydigan xatolar
- Figurali qavsli callback da
returnni unutish —undefinedqiymatlar hosil bo‘ladi. mapichida asl massivni o‘zgartirish.reducega boshlang‘ich qiymatni uzatmaslik.- Ortiqcha parametrli funksiyani to‘g‘ridan-to‘g‘ri uzatish:
["1", "2", "3"].map(parseInt)[1, NaN, NaN]beradi, chunkimapindeksni ham uzatadi va u sanoq tizimi asosiga aylanadi.