O'zbek

JavaScript massivlari yordamida funksional dasturlash imkoniyatlarini oching. O'rnatilgan metodlar yordamida ma'lumotlaringizni samarali o'zgartirish, filtrlash va qisqartirishni o'rganing.

JavaScript Massivlari Bilan Funksional Dasturlashni O'zlashtirish

Doimiy rivojlanayotgan veb-ishlab chiqish sohasida JavaScript asosiy tamal toshi bo'lib qolmoqda. Ob'ektga yo'naltirilgan va imperativ dasturlash paradigmalari uzoq vaqt davomida ustunlik qilib kelgan bo'lsa-da, funksional dasturlash (FD) tobora ommalashib bormoqda. FD o'zgarmaslik, sof funksiyalar va deklarativ kodga urg'u beradi, bu esa yanada mustahkam, qo'llab-quvvatlanadigan va bashorat qilinadigan ilovalarga olib keladi. JavaScript-da funksional dasturlashni qo'llashning eng kuchli usullaridan biri bu uning mahalliy massiv metodlaridan foydalanishdir.

Ushbu keng qamrovli qo'llanma JavaScript massivlaridan foydalangan holda funksional dasturlash tamoyillari kuchini qanday ishga solish mumkinligini chuqur o'rganadi. Biz asosiy tushunchalarni ko'rib chiqamiz va ularni map, filter va reduce kabi metodlar yordamida qanday qo'llashni namoyish etamiz, bu esa ma'lumotlar bilan ishlash uslubingizni o'zgartiradi.

Funksional Dasturlash Nima?

JavaScript massivlariga sho'ng'ishdan oldin, funksional dasturlashni qisqacha ta'riflab o'taylik. Aslida, FD - bu hisoblashni matematik funksiyalarni baholash sifatida qabul qiladigan va holatni o'zgartirish hamda o'zgaruvchan ma'lumotlardan qochadigan dasturlash paradigmasidir. Asosiy tamoyillarga quyidagilar kiradi:

Ushbu tamoyillarni qabul qilish, ayniqsa murakkab ilovalarda, tushunish, sinovdan o'tkazish va tuzatish osonroq bo'lgan kodga olib kelishi mumkin. JavaScript massiv metodlari bu tushunchalarni amalga oshirish uchun juda mos keladi.

JavaScript Massiv Metodlarining Kuchi

JavaScript massivlari an'anaviy sikllarga (masalan, for yoki while) murojaat qilmasdan murakkab ma'lumotlar manipulyatsiyasiga imkon beruvchi boy o'rnatilgan metodlar to'plami bilan jihozlangan. Bu metodlar ko'pincha yangi massivlar qaytaradi, bu esa o'zgarmaslikni rag'batlantiradi va funksional yondashuvni ta'minlovchi callback funksiyalarni qabul qiladi.

Keling, eng asosiy funksional massiv metodlarini ko'rib chiqaylik:

1. Array.prototype.map()

map() metodi chaqiruvchi massivdagi har bir element uchun taqdim etilgan funksiyani chaqirish natijalari bilan to'ldirilgan yangi massiv yaratadi. Bu massivning har bir elementini yangi narsaga aylantirish uchun idealdir.

Sintaksis:

array.map(callback(currentValue[, index[, array]])[, thisArg])

Asosiy Xususiyatlari:

Misol: Har Bir Sonni Ikki Barobar Oshirish

Tasavvur qiling, sizda sonlar massivi bor va siz har bir son ikki barobarga oshirilgan yangi massiv yaratmoqchisiz.

const numbers = [1, 2, 3, 4, 5];

// Transformatsiya uchun map dan foydalanish
const doubledNumbers = numbers.map(number => number * 2);

console.log(numbers); // Natija: [1, 2, 3, 4, 5] (asl massiv o'zgarishsiz qoladi)
console.log(doubledNumbers); // Natija: [2, 4, 6, 8, 10]

Misol: Ob'ektlardan Xususiyatlarni Ajratib Olish

Keng tarqalgan holatlardan biri bu ob'ektlar massividan ma'lum xususiyatlarni ajratib olishdir. Aytaylik, bizda foydalanuvchilar ro'yxati bor va biz faqat ularning ismlarini olmoqchimiz.

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const userNames = users.map(user => user.name);

console.log(userNames); // Natija: ['Alice', 'Bob', 'Charlie']

2. Array.prototype.filter()

filter() metodi taqdim etilgan funksiya tomonidan amalga oshirilgan sinovdan o'tgan barcha elementlar bilan yangi massiv yaratadi. U shart asosida elementlarni tanlash uchun ishlatiladi.

Sintaksis:

array.filter(callback(element[, index[, array]])[, thisArg])

Asosiy Xususiyatlari:

Misol: Juft Sonlarni Filtrlash

Keling, sonlar massivini faqat juft sonlarni saqlab qolish uchun filtrlaymiz.

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Juft sonlarni tanlash uchun filter dan foydalanish
const evenNumbers = numbers.filter(number => number % 2 === 0);

console.log(numbers); // Natija: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(evenNumbers); // Natija: [2, 4, 6, 8, 10]

Misol: Faol Foydalanuvchilarni Filtrlash

Foydalanuvchilar massividan faol deb belgilangan foydalanuvchilarni filtrlaymiz.

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
  { id: 4, name: 'David', isActive: false }
];

const activeUsers = users.filter(user => user.isActive);

console.log(activeUsers); 
/* Natija:
[
  { id: 1, name: 'Alice', isActive: true },
  { id: 3, name: 'Charlie', isActive: true }
]
*/

3. Array.prototype.reduce()

reduce() metodi massivning har bir elementi uchun foydalanuvchi tomonidan taqdim etilgan “reducer” callback funksiyasini ketma-ket bajaradi va avvalgi elementdagi hisoblashdan olingan qaytarilgan qiymatni uzatadi. Reducer-ni massivning barcha elementlari bo'ylab ishga tushirishning yakuniy natijasi bitta qiymatdir.

Bu, ehtimol, massiv metodlarining eng ko'p qirralisi bo'lib, ko'plab funksional dasturlash naqshlarining asosidir, bu sizga massivni bitta qiymatga (masalan, yig'indi, ko'paytma, hisob yoki hatto yangi ob'ekt yoki massiv) “qisqartirish” imkonini beradi.

Sintaksis:

array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

Asosiy Xususiyatlari:

Misol: Sonlarni Yig'ish

Keling, massivimizdagi barcha sonlarni yig'amiz.

const numbers = [1, 2, 3, 4, 5];

// Sonlarni yig'ish uchun reduce dan foydalanish
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0); // 0 - bu initialValue

console.log(sum); // Natija: 15

Tushuntirish:

Misol: Ob'ektlarni Xususiyat Bo'yicha Guruhlash

Biz reduce yordamida ob'ektlar massivini qiymatlar ma'lum bir xususiyat bo'yicha guruhlangan ob'ektga aylantirishimiz mumkin. Keling, foydalanuvchilarimizni ularning `isActive` holati bo'yicha guruhlaymiz.

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
  { id: 4, name: 'David', isActive: false }
];

const groupedUsers = users.reduce((acc, user) => {
  const status = user.isActive ? 'active' : 'inactive';
  if (!acc[status]) {
    acc[status] = [];
  }
  acc[status].push(user);
  return acc;
}, {}); // Bo'sh ob'ekt {} - bu initialValue

console.log(groupedUsers);
/* Natija:
{
  active: [
    { id: 1, name: 'Alice', isActive: true },
    { id: 3, name: 'Charlie', isActive: true }
  ],
  inactive: [
    { id: 2, name: 'Bob', isActive: false },
    { id: 4, name: 'David', isActive: false }
  ]
}
*/

Misol: Takrorlanishlarni Sanash

Keling, ro'yxatdagi har bir mevaning chastotasini sanaymiz.

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

const fruitCounts = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});

console.log(fruitCounts); // Natija: { apple: 3, banana: 2, orange: 1 }

4. Array.prototype.forEach()

forEach() yangi massiv qaytarmasa va uning asosiy maqsadi har bir massiv elementi uchun funksiyani bajarish bo'lgani uchun ko'pincha imperativroq deb hisoblansa-da, u hali ham funksional naqshlarda rol o'ynaydigan asosiy metoddir, ayniqsa yon ta'sirlar zarur bo'lganda yoki o'zgartirilgan natijaga ehtiyoj sezmasdan iteratsiya qilishda.

Sintaksis:

array.forEach(callback(element[, index[, array]])[, thisArg])

Asosiy Xususiyatlari:

Misol: Har Bir Elementni Konsolga Chiqarish

const messages = ['Hello', 'Functional', 'World'];

messages.forEach(message => console.log(message));
// Natija:
// Hello
// Functional
// World

Eslatma: O'zgartirishlar va filtrlash uchun, o'zgarmaslik va deklarativ tabiati tufayli map va filter afzalroqdir. Natijalarni yangi strukturaga yig'masdan har bir element uchun maxsus amal bajarishingiz kerak bo'lganda forEach dan foydalaning.

5. Array.prototype.find() va Array.prototype.findIndex()

Bu metodlar massivdagi ma'lum elementlarni topish uchun foydalidir.

Misol: Foydalanuvchini Topish

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const bob = users.find(user => user.name === 'Bob');
const bobIndex = users.findIndex(user => user.name === 'Bob');
const nonExistentUser = users.find(user => user.name === 'David');
const nonExistentIndex = users.findIndex(user => user.name === 'David');

console.log(bob); // Natija: { id: 2, name: 'Bob' }
console.log(bobIndex); // Natija: 1
console.log(nonExistentUser); // Natija: undefined
console.log(nonExistentIndex); // Natija: -1

6. Array.prototype.some() va Array.prototype.every()

Bu metodlar massivdagi barcha elementlar taqdim etilgan funksiya tomonidan amalga oshirilgan sinovdan o'tishini tekshiradi.

Misol: Foydalanuvchi Holatini Tekshirish

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true }
];

const hasInactiveUser = users.some(user => !user.isActive);
const allAreActive = users.every(user => user.isActive);

console.log(hasInactiveUser); // Natija: true (chunki Bob nofaol)
console.log(allAreActive); // Natija: false (chunki Bob nofaol)

const allUsersActive = users.filter(user => user.isActive).length === users.length;
console.log(allUsersActive); // Natija: false

// To'g'ridan-to'g'ri every dan foydalangan holda alternativ
const allUsersActiveDirect = users.every(user => user.isActive);
console.log(allUsersActiveDirect); // Natija: false

Murakkab Operatsiyalar Uchun Massiv Metodlarini Zanjir Qilish

JavaScript massivlari bilan funksional dasturlashning haqiqiy kuchi bu metodlarni bir-biriga zanjir qilganingizda namoyon bo'ladi. Ushbu metodlarning aksariyati yangi massivlar qaytarganligi sababli (forEach dan tashqari), siz bir metodning natijasini boshqasining kiritishiga uzluksiz ravishda yo'naltirishingiz mumkin, bu esa nafis va o'qilishi oson ma'lumotlar quvurlarini yaratadi.

Misol: Faol Foydalanuvchilarning Ismlarini Topish va Ularning ID'larini Ikki Barobar Oshirish

Keling, barcha faol foydalanuvchilarni topamiz, ularning ismlarini ajratib olamiz va so'ngra har bir ismning oldiga *filtrlangan* ro'yxatdagi indeksini ifodalovchi raqam qo'shilgan va ularning ID'lari ikki barobarga oshirilgan yangi massiv yaratamiz.

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
  { id: 4, name: 'David', isActive: true },
  { id: 5, name: 'Eve', isActive: false }
];

const processedActiveUsers = users
  .filter(user => user.isActive) // Faqat faol foydalanuvchilarni olish
  .map((user, index) => ({      // Har bir faol foydalanuvchini o'zgartirish
    name: `${index + 1}. ${user.name}`,
    doubledId: user.id * 2
  }));

console.log(processedActiveUsers);
/* Natija:
[
  { name: '1. Alice', doubledId: 2 },
  { name: '2. Charlie', doubledId: 6 },
  { name: '3. David', doubledId: 8 }
]
*/

Ushbu zanjirli yondashuv deklarativdir: biz aniq sikl boshqaruvisiz bosqichlarni (filtr, so'ngra map) belgilaymiz. U shuningdek o'zgarmasdir, chunki har bir qadam yangi massiv yoki ob'ekt hosil qiladi va asl users massivini o'zgarishsiz qoldiradi.

Amalda O'zgarmaslik

Funksional dasturlash o'zgarmaslikka qattiq tayanadi. Bu shuni anglatadiki, mavjud ma'lumotlar tuzilmalarini o'zgartirish o'rniga, siz kerakli o'zgarishlar bilan yangilarini yaratasiz. JavaScript-ning map, filter va slice kabi massiv metodlari yangi massivlar qaytarish orqali buni tabiatan qo'llab-quvvatlaydi.

Nima uchun o'zgarmaslik muhim?

An'anaviy ravishda massivni o'zgartiradigan operatsiyani (masalan, element qo'shish yoki olib tashlash) bajarishingiz kerak bo'lganda, siz slice, spread sintaksisi (...) kabi metodlardan yoki boshqa funksional metodlarni birlashtirish orqali o'zgarmaslikka erishishingiz mumkin.

Misol: Elementni O'zgarmas Holda Qo'shish

const originalArray = [1, 2, 3];

// Imperativ usul (originalArray ni o'zgartiradi)
// originalArray.push(4);

// Spread sintaksisi yordamida funksional usul
const newArrayWithPush = [...originalArray, 4];
console.log(originalArray); // Natija: [1, 2, 3]
console.log(newArrayWithPush); // Natija: [1, 2, 3, 4]

// Slice va birlashtirish yordamida funksional usul (hozir kamroq tarqalgan)
const newArrayWithSlice = originalArray.slice(0, originalArray.length).concat(4);
console.log(newArrayWithSlice); // Natija: [1, 2, 3, 4]

Misol: Elementni O'zgarmas Holda Olib Tashlash

const originalArray = [1, 2, 3, 4, 5];

// 2-indeksdagi elementni (qiymati 3) olib tashlash

// Slice va spread sintaksisi yordamida funksional usul
const newArrayAfterSplice = [
  ...originalArray.slice(0, 2),
  ...originalArray.slice(3)
];
console.log(originalArray); // Natija: [1, 2, 3, 4, 5]
console.log(newArrayAfterSplice); // Natija: [1, 2, 4, 5]

// Ma'lum bir qiymatni olib tashlash uchun filter dan foydalanish
const newValueToRemove = 3;
const arrayWithoutValue = originalArray.filter(item => item !== newValueToRemove);
console.log(arrayWithoutValue); // Natija: [1, 2, 4, 5]

Eng Yaxshi Amaliyotlar va Ilg'or Texnikalar

Funksional massiv metodlari bilan qulayroq bo'lganingiz sari, ushbu amaliyotlarni ko'rib chiqing:

Misol: Ma'lumotlarni Jamlashga Funksional Yondashuv

Tasavvur qiling, sizda turli mintaqalardan savdo ma'lumotlari bor va har bir mintaqa uchun umumiy savdolarni hisoblashni, so'ngra eng yuqori savdoga ega mintaqani topishni xohlaysiz.

const salesData = [
  { region: 'North', amount: 100 },
  { region: 'South', amount: 150 },
  { region: 'North', amount: 120 },
  { region: 'East', amount: 200 },
  { region: 'South', amount: 180 },
  { region: 'North', amount: 90 }
];

// 1. reduce yordamida har bir mintaqa bo'yicha umumiy savdolarni hisoblash
const salesByRegion = salesData.reduce((acc, sale) => {
  acc[sale.region] = (acc[sale.region] || 0) + sale.amount;
  return acc;
}, {});

// salesByRegion quyidagicha bo'ladi: { North: 310, South: 330, East: 200 }

// 2. Yig'ilgan ob'ektni keyingi ishlov berish uchun ob'ektlar massiviga o'tkazish
const salesArray = Object.keys(salesByRegion).map(region => ({
  region: region,
  totalAmount: salesByRegion[region]
}));

// salesArray quyidagicha bo'ladi: [
//   { region: 'North', totalAmount: 310 },
//   { region: 'South', totalAmount: 330 },
//   { region: 'East', totalAmount: 200 }
// ]

// 3. reduce yordamida eng yuqori savdoga ega mintaqani topish
const highestSalesRegion = salesArray.reduce((max, current) => {
  return current.totalAmount > max.totalAmount ? current : max;
}, { region: '', totalAmount: -Infinity }); // Juda kichik son bilan ishga tushirish

console.log('Mintaqalar bo\'yicha savdolar:', salesByRegion);
console.log('Savdolar massivi:', salesArray);
console.log('Eng yuqori savdoga ega mintaqa:', highestSalesRegion);

/*
Natija:
Mintaqalar bo'yicha savdolar: { North: 310, South: 330, East: 200 }
Savdolar massivi: [
  { region: 'North', totalAmount: 310 },
  { region: 'South', totalAmount: 330 },
  { region: 'East', totalAmount: 200 }
]
Eng yuqori savdoga ega mintaqa: { region: 'South', totalAmount: 330 }
*/

Xulosa

JavaScript massivlari bilan funksional dasturlash shunchaki uslubiy tanlov emas; bu toza, bashorat qilinadigan va mustahkamroq kod yozishning kuchli usulidir. map, filter va reduce kabi metodlarni qabul qilish orqali siz o'z ma'lumotlaringizni samarali tarzda o'zgartirishingiz, so'rashingiz va jamlashingiz mumkin, shu bilan birga funksional dasturlashning asosiy tamoyillariga, xususan, o'zgarmaslik va sof funksiyalarga amal qilasiz.

JavaScript ishlab chiqish bo'yicha sayohatingizni davom ettirar ekansiz, ushbu funksional naqshlarni kundalik ish jarayoningizga integratsiyalash, shubhasiz, yanada qo'llab-quvvatlanadigan va kengaytiriladigan ilovalarga olib keladi. Loyihalaringizda ushbu massiv metodlarini sinab ko'rishdan boshlang va tez orada ularning ulkan qiymatini kashf etasiz.