Arrays

...

Arrays

Obyektlar sizga kalitlangan qiymatlar to'plamini saqlash imkonini beradi. Bu yaxshi.

Ammo ko'pincha bizga tartiblangan to'plam kerak bo'ladi, ya'ni birinchi, ikkinchi, uchinchi elementlar va hokazo. Misol uchun, biz buni foydalanuvchilar, tovarlar, HTML elementlarining ro'yxatini saqlash uchun ishlatamiz.

Bu yerda obyektni ishlatish qulay emas, chunki u elementlarning tartibini boshqarish uchun metodlarni taqdim etmaydi. Biz yangi xususiyat qo'sha olmaymiz, mavjud xususiyatlar orasida bo'lishi mumkin. Obyektlar shunday ishlatilmagan.

Tartiblangan to'plamlarni saqlash uchun maxsus ma'lumotlar tuzilmasi mavjud - Array.

E'lon qilish

Bo'sh massiv yaratish uchun ikkita sintaksis mavjud:

let arr = new Array();
let arr = [];

Ko'pincha ikkinchi sintaksis ishlatiladi. Biz boshlang'ich elementlarni qavslar ichida ko'rsatishimiz mumkin:

let fruits = ['Apple', 'Orange', 'Plum'];

Massiv elementlari raqamlangan, noldan boshlanadi.

Elementni uning raqamida olishimiz mumkin:

let fruits = ['Apple', 'Orange', 'Plum'];
 
alert(fruits[0]); // Apple
alert(fruits[1]); // Orange
alert(fruits[2]); // Plum

Elementni almashtirish mumkin:

fruits[2] = 'Pear'; // endi ["Apple", "Orange", "Pear"]

Yangi element qo'shish mumkin:

fruits[3] = 'Lemon'; // endi ["Apple", "Orange", "Pear", "Lemon"]

Massivdagi elementlar soni uning uzunligini bildiradi:

let fruits = ['Apple', 'Orange', 'Plum'];
 
alert(fruits.length); // 3

Butun massivni ko'rsatish uchun alert ishlatilishi mumkin:

let fruits = ['Apple', 'Orange', 'Plum'];
 
alert(fruits); // Apple,Orange,Plum

Massiv har qanday turdagi elementlarni saqlashi mumkin.

Masalan:

// turli qiymatlar
let arr = [
  'Apple',
  { name: 'John' },
  true,
  function () {
    alert('hello');
  },
];
 
// 1-indeksdagi obyektdan nomini olish
alert(arr[1].name); // John
 
// 3-indeksdagi funksiyani chaqirish
arr[3](); // hello

Trailing comma

Massiv, obyekt kabi, vergul bilan tugashi mumkin:

let fruits = ['Apple', 'Orange', 'Plum'];

"Trailing comma" uslubi elementlarni qo'shish/olish osonroq qiladi, chunki barcha qatorlar bir xil bo'ladi.

Oxirgi elementlarni "at" bilan olish

Bu yangi qo'shilgan xususiyat.

Agar massivning oxirgi elementini olishni istasak:

Ba'zi dasturlash tillari negativ indekslar yordamida bu maqsadni bajarishga ruxsat beradi, masalan fruits[-1].

JavaScript'da bu ishlamaydi. Natija undefined bo'ladi, chunki indeks kvadrat qavslar ichida bevosita olinadi.

Oxirgi element indeksini aniq hisoblashimiz mumkin va shundan foydalanishimiz mumkin: fruits[fruits.length - 1].

let fruits = ['Apple', 'Orange', 'Plum'];
 
alert(fruits[fruits.length - 1]); // Plum

Bir oz noqulay, shunday emasmi? Biz o'zgaruvchining nomini ikki marta yozishimiz kerak.

Yaxshi yangilik: qisqaroq sintaksis mavjud: fruits.at(-1):

let fruits = ['Apple', 'Orange', 'Plum'];
 
// fruits[fruits.length-1] ga teng
alert(fruits.at(-1)); // Plum

Demak, arr.at(i):

  • i >= 0 bo'lsa, arr[i] bilan bir xil.
  • Negativ i qiymatlari uchun, massivning oxiridan orqaga qadam qo'yadi.

pop/push, shift/unshift metodlari

Massivlar ko'pincha "queue" (navbat) ma'lumotlar tuzilmasi sifatida ishlatiladi. Bu, kompyuter fanida, tartiblangan elementlar to'plamidir va ikkita amaliyotni qo'llab-quvvatlaydi:

  • push - elementni oxiriga qo'shadi.
  • shift - boshlanishdan elementni oladi, navbatni oldinga siljitib, 2-chi elementni 1-chi qilish.
Queue image

Massivlar ushbu ikkita operatsiyani qo'llab-quvvatlaydi.

Ko'pincha buni amalga oshirish zarurati tug'iladi. Misol uchun, ekranlarda ko'rsatilishi kerak bo'lgan xabarlar navbati.

Massivlar yana bir ma'lumotlar tuzilmasi - "stack" (stak) sifatida ishlatilishi mumkin.

Bu ikkita operatsiyani qo'llab-quvvatlaydi:

  • push - elementni oxiriga qo'shadi.
  • pop - elementni oxiridan oladi.

Shunday qilib, yangi elementlar faqat "oxiridan" qo'shiladi yoki olinadi.

Stak ko'pincha kartalar to'plami sifatida tasvirlanadi: yangi kartalar yuqoriga qo'shiladi yoki yuqoridan olinadi.

Stack image

Stakda eng oxirgi qo'shilgan element birinchi bo'lib olinadi, bu LIFO (Last-In-First-Out) prinsipiga mos keladi. Navbatda FIFO (First-In-First-Out) prinsipiga mos keladi.

JavaScript'dagi massivlar navbat va stak sifatida ishlatilishi mumkin. Ular elementlarni qo'shish/olish imkonini beradi, boshlanishidan yoki oxiridan.

"Deque" deb ataladigan ma'lumotlar tuzilmasi bu imkoniyatni taqdim etadi.

Oxiridagi metodlar:

pop

Massivning oxirgi elementini olib, qaytaradi:

let fruits = ['Apple', 'Orange', 'Pear'];
 
alert(fruits.pop()); // "Pear" ni olib, ko'rsatadi
 
alert(fruits); // Apple, Orange

fruits.pop() va fruits.at(-1) ikkalasi ham massivning oxirgi elementini qaytaradi, lekin fruits.pop() massivni o'zgartiradi va uni olib tashlaydi.

push

Elementni massivning oxiriga qo'shadi:

let fruits = ['Apple', 'Orange'];
 
fruits.push('Pear');
 
alert(fruits); // Apple, Orange, Pear

fruits.push(...) fruits[fruits.length] = ... bilan tengdir.

shift

Massivning birinchi elementini olib, qaytaradi:

let fruits = ['Apple', 'Orange', 'Pear'];
 
alert(fruits.shift()); // Apple ni olib, ko'rsatadi
 
alert(fruits); // Orange, Pear

unshift

Elementni massivning boshlanishiga qo'shadi:

let fruits = ['Orange', 'Pear'];
 
fruits.unshift('Apple');
 
alert(fruits); // Apple, Orange, Pear

push va unshift metodlari bir vaqtning o'zida bir nechta element qo'shishi mumkin:

let fruits = ['Apple'];
 
fruits.push('Orange', 'Peach');
fruits.unshift('Pineapple', 'Lemon');
 
// ["Pineapple", "Lemon", "Apple", "Orange", "Peach"]
alert(fruits);

Internals

Massiv - maxsus obyekt turidir. Massivni arr[0] kabi kvadrat qavslar yordamida olish obyekt sintaksisidan kelib chiqadi. Bu aslida obj[key] kabi, bu yerda arr obyekt, raqamlar esa kalit sifatida ishlatiladi.

Massivlar obyektlarni kengaytiradi, tartiblangan ma'lumotlar to'plamlarini ishlash uchun maxsus metodlar va uzunlik xususiyatini taqdim etadi. Ammo asosan bu obyekt sifatida ishlaydi.

JavaScript'da sakkizta asosiy ma'lumot turi mavjud (ko'proq ma'lumot uchun Ma'lumot turlari bo'limiga qarang). Massiv obyekt bo'lib, shuning uchun obyekt sifatida ishlaydi.

Misol uchun, massiv havola orqali nusxalanadi:

let fruits = ["Banana"];
 
let arr = fruits; // havola orqali nusxalash (ikki o'zgaruvchi bir xil massivga havola qiladi)
 
alert( arr === fruits ); // true
 
arr.push("Pear"); // havola orqali massivni o'zgartiradi
 
alert( fruits ); // Banana, Pear - 2 ta element

Ammo massivlarni haqiqatan ham maxsus qiladigan narsa ularning ichki ko'rsatmasidir. Dastur o'z elementlarini ketma-ket xotira hududida saqlashga harakat qiladi, bu bobdagi tasvirlar singari, va boshqa optimallashtirishlar ham mavjud, massivlar juda tez ishlashi uchun.

Lekin agar biz massivni "tartiblangan to'plam" sifatida ishlashni to'xtatib, uni oddiy obyekt sifatida ishlatsak, barcha optimallashtirishlar buziladi.

Masalan, texnik jihatdan biz buni amalga oshirishimiz mumkin:

let fruits = []; // massiv yaratamiz
 
fruits[99999] = 5; // indeks bilan xususiyat tayinlash, uzunlikdan katta
 
fruits.age = 25; // tasodifiy nomli xususiyat yaratish

Bu mumkin, chunki massivlar asosan obyektlardir. Ularga har qanday xususiyat qo'shishimiz mumkin.

Lekin dastur massivni oddiy obyekt sifatida ko'radi. Massivga xos optimallashtirishlar bu holat uchun mos kelmaydi va ular o'chiriladi, shuning uchun ularning foydalari yo'qoladi.

Massivlarni noto'g'ri ishlatish usullari:

  • Raqamli bo'lmagan xususiyat qo'shish, masalan arr.test = 5.
  • Bo'sh joylar yaratish, masalan: arr[0] qo'shish va keyin arr[1000] qo'shish (va ularning orasida hech narsa bo'lmaydi).
  • Massivni teskari tartibda to'ldirish, masalan arr[1000], arr[999] va hokazo.

Massivlarni tartiblangan ma'lumotlar bilan ishlash uchun maxsus strukturalar sifatida tasavvur qiling. Ular bu maqsad uchun maxsus metodlarni taqdim etadi. JavaScript dvigatellari massivlarni ketma-ket tartiblangan ma'lumotlar bilan ishlash uchun ehtiyotkorlik bilan sozlangan, shuning uchun ulardan shu tarzda foydalaning. Agar tasodifiy kalitlar kerak bo'lsa, ehtimol siz oddiy obyekt talab qilasiz.

Ishlash tezligi

push/pop metodlari tez ishlaydi, shift/unshift esa sekin.

Array speed image

Nega massivning oxirida ishlash boshida ishlashdan tezroq? Keling, bajarilish jarayonini ko'rib chiqamiz:

fruits.shift(); // 1 ta elementni boshlanishdan olish

Index 0 bo'lgan elementni olib tashlash kifoya emas. Boshqa elementlar ham qayta raqamlanishi kerak.

shift operatsiyasi 3 narsani bajarishi kerak:

  1. Index 0 bo'lgan elementni olib tashlash.
  2. Barcha elementlarni chapga ko'chirish, index 1 dan 0 gacha, 2 dan 1 gacha va hokazo.
  3. Uzunlik xususiyatini yangilash.
Array shift image

Massivda ko'proq elementlar bo'lsa, ularni ko'chirish uchun ko'proq vaqt ketadi, ko'proq xotira operatsiyalari.

unshift bilan ham shunday. Massivning boshlanishiga element qo'shish uchun, avvalgi elementlarni o'ngga ko'chirishimiz kerak, ularning indekslarini oshirishimiz kerak.

push/pop usullari nima bilan ishlaydi? Ular hech narsani ko'chirishlari shart emas. Oxiridan elementni olish uchun pop metodi indeksni tozalaydi va uzunlikni qisqartiradi.

pop operatsiyasi uchun bajariladigan harakatlar:

fruits.pop(); // 1 ta elementni oxiridan olish
Array pop image

pop metodi hech narsani ko'chirish kerak emas, chunki boshqa elementlar o'z indekslarini saqlaydi. Shuning uchun, bu juda tez ishlaydi.

push metodida ham shunday.

Tsikl

Massiv elementlarini aylantirishning eng eski usullaridan biri bu indekslar bo'yicha for tsiklidır:

let arr = ["Apple", "Orange", "Pear"];
 
for (let i = 0; i < arr.length; i++) {
  alert( arr[i] );
}

Lekin massivlar uchun boshqa tsikl shakli mavjud, for..of:

let fruits = ["Apple", "Orange", "Plum"];
 
// massiv elementlari bo'yicha iteratsiya qiladi
for (let fruit of fruits) {
  alert( fruit );
}

for..of sizga joriy elementning raqamini bermaydi, faqat uning qiymatini beradi, lekin ko'p hollarda bu yetarli. Va bu qisqaroq.

Texnik jihatdan, massivlar obyektlar bo'lgani uchun, for..in ni ham ishlatish mumkin:

let arr = ["Apple", "Orange", "Pear"];
 
for (let key in arr) {
  alert( arr[key] ); // Apple, Orange, Pear
}

Lekin bu aslida yaxshi fikr emas. Bunda ba'zi muammolar mavjud:

  • for..in tsikli barcha xususiyatlarni iteratsiya qiladi, faqat raqamli bo'lganlarini emas.
  • Brauzerlar va boshqa muhitlarda "massivga o'xshash" obyektlar mavjud, ular massivlarga o'xshaydi. Ya'ni, ular uzunlik va indekslar xususiyatlariga ega, lekin ular boshqa raqamli bo'lmagan xususiyatlar va metodlarga ham ega bo'lishi mumkin, biz odatda ulardan foydalanmaymiz. for..in tsikli ularga ham qaraydi. Agar biz massivga o'xshash obyektlar bilan ishlashimiz kerak bo'lsa, bu "qo'shimcha" xususiyatlar muammo bo'lishi mumkin.

for..in tsikli umumiy obyektlar uchun optimallashtirilgan, massivlar uchun emas, shuning uchun 10-100 baravar sekinroq ishlaydi. Albatta, bu hali ham juda tez. Tezlik faqat choklarda muhim bo'lishi mumkin. Shunga qaramay, farqni bilishimiz kerak.

Umuman olganda, massivlar uchun for..in ishlatmaslik kerak.

Uzunlik haqida

Uzunlik xususiyati massivni o'zgartirganda avtomatik yangilanadi. Aniqrog'i, bu massivdagi qiymatlar soni emas, balki eng katta raqamli indeks plus bir.

Masalan, katta indeksdagi bitta element katta uzunlik beradi:

let fruits = [];
fruits[123] = "Apple";
 
alert( fruits.length ); // 124

Odatda, biz massivlarni shunday ishlatmaymiz.

Uzunlik xususiyati haqida yana bir qiziqarli narsa, u yozilishi mumkin.

Agar biz uni qo'lda oshirsak, hech qanday qiziqarli narsa bo'lmaydi. Ammo agar biz qisqartirsak, massiv qisqaradi. Bu jarayon qaytarib bo'lmaydi, misol:

let arr = [1, 2, 3, 4, 5];
 
arr.length = 2; // 2 ta elementga qisqartiradi
alert( arr ); // [1, 2]
 
arr.length = 5; // uzunlikni qaytaradi
alert( arr[3] ); // undefined: qiymatlar qaytmaydi

Shuning uchun, massivni tozalashning eng oddiy usuli: arr.length = 0;.

new Array()

Massiv yaratish uchun yana bir sintaksis mavjud:

let arr = new Array("Apple", "Pear", "va hokazo");

Bu

kamdan-kam ishlatiladi, chunki kvadrat qavslar [] qisqaroq. Shuningdek, unda bir qiziqarli xususiyat bor.

Agar new Array faqat bitta argument bilan, bu son bo'lsa, u elementlarsiz, lekin berilgan uzunlik bilan massiv yaratadi.

Keling, qanday qilib o'zingizni o'qishingiz mumkinligini ko'ramiz:

let arr = new Array(2); // bu [2] massivni yaratadimi?
 
alert( arr[0] ); // undefined! hech qanday elementlar mavjud emas.
 
alert( arr.length ); // uzunlik 2

Bunday kutilmagan natijalardan qochish uchun, odatda, kvadrat qavslarni ishlatamiz, agar biz haqiqatan ham nima qilayotganimizni bilmasak.

Ko'p o'lchovli massivlar

Massivlar boshqa massivlarni o'z ichiga olishi mumkin. Buni ko'p o'lchamli massivlar uchun, masalan, matritsalarni saqlash uchun ishlatishimiz mumkin:

let matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];
 
alert( matrix[0][1] ); // 2, birinchi ichki massivning ikkinchi qiymati

toString

Massivlarning o'ziga xos toString metodlari mavjud bo'lib, ularni vergul bilan ajratilgan ro'yxat sifatida qaytaradi.

Masalan:

let arr = [1, 2, 3];
 
alert( arr ); // 1,2,3
alert( String(arr) === '1,2,3' ); // true

Shuningdek, buni sinab ko'ring:

alert( [] + 1 ); // "1"
alert( [1] + 1 ); // "11"
alert( [1,2] + 1 ); // "1,21"

Massivlar Symbol.toPrimitive yoki to'g'ri valueOf'ga ega emas, ular faqat toString konversiyasini amalga oshiradi, shuning uchun bu yerda [] bo'sh satrga, [1] "1" ga va [1,2] "1,2" ga aylanadi.

Agar ikkilik plus + operatori stringga narsa qo'shsa, bu ham stringga aylantiradi, shuning uchun keyingi qadam quyidagicha bo'ladi:

alert( "" + 1 ); // "1"
alert( "1" + 1 ); // "11"
alert( "1,2" + 1 ); // "1,21"

Massivlarni solishtirmang

JavaScript'da, ba'zi boshqa dasturlash tillaridan farqli o'laroq, massivlarni == operatori bilan solishtirmang.

Bu operator massivlar uchun maxsus ishlov bermaydi, ularni har qanday obyektlar kabi ishlaydi.

Eslatib o'tamiz, qoidalar:

  • Ikki obyekt == bilan faqat bir xil obyektlarga havola qilsalar tengdir.
  • Agar == ning bir argumenti obyekt bo'lsa, va ikkinchisi primitive bo'lsa, obyekt primitive ga konvertatsiya qilinadi, Ma'lumotni primitive ga konvertatsiya qilish bo'limida tushuntirilganidek.

… Null va undefined istisno, ular bir-biriga teng va boshqa hech narsaga teng emas.

Qattiq solishtirish === esa yanada sodda, chunki u turlarni konvertatsiya qilmaydi.

Shuning uchun, agar biz massivlarni == bilan solishtirsak, ular hech qachon teng bo'lmaydi, faqat ikkala o'zgaruvchi bir xil massivga havola qilsa.

Misol:

alert( [] == [] ); // false
alert( [0] == [0] ); // false

Bu massivlar texnik jihatdan turli obyektlardir. Shunday qilib, ular teng emas. == operatori elementlarni element-bo'yicha taqqoslamaydi.

Primitive bilan solishtirish ham ba'zan g'alati natijalarni berishi mumkin:

alert( 0 == [] ); // true
 
alert( '0' == [] ); // false

Bu yerda, ikkala holatda ham, biz primitive bilan massiv ob'ektini solishtiryapmiz. Shuning uchun massiv [] primitive uchun konvertatsiya qilinadi va bo'sh satr '' ga aylanadi.

So'ngra, solishtirish jarayoni primitivlar bilan davom etadi, Ma'lumotlarni konvertatsiya qilish bo'limida tushuntirilganidek:

// [] bo'sh satrga aylantirilgandan so'ng

alert( 0 == '' ); // true, chunki `''` 0 ga konvertatsiya qilinadi
 
alert( '0' == '' ); // false, tur konvertatsiya qilinmaydi, turli satrlar

Shunday qilib, massivlarni qanday solishtirish kerak?

Bu juda oddiy: == operatoridan foydalanmang. Buning o'rniga, massivlarni item-bo'yicha solishtiring, tsikl orqali yoki keyingi bo'limda tushuntirilgan iteratsiya metodlaridan foydalanib.

Xulosa

Massiv - maxsus obyekt turidir, tartiblangan ma'lumotlarni saqlash va boshqarish uchun moslashgan.

Deklaratsiya:

  • Kvadrat qavslar (odatiy)
let arr = [item1, item2...];
  • new Array (nadir hollarda)
let arr = new Array(item1, item2...);

Yagona argument bilan new Array chaqirilsa, bu elementlarsiz, lekin berilgan uzunlik bilan massiv yaratadi.

Uzunlik xususiyati - massiv uzunligi yoki, aniqrog'i, uning oxirgi raqamli indeks plus bir. Bu massiv metodlari tomonidan avtomatik sozlanadi.

Agar biz uzunlikni qo'lda qisqartirsak, massiv qisqaradi.

Elementlarni olish:

  • Elementni indeks orqali olishimiz mumkin, masalan, arr[0]
  • at(i) metodini ishlatish mumkin, bu manfiy indekslarni ruxsat etadi. Manfiy i qiymatlari oxirdan orqaga qadam bosadi. Agar i >= 0, bu arr[i] bilan bir xil ishlaydi.

Massivni deque sifatida ishlatish mumkin:

  • push(...items) - elementlarni oxiriga qo'shadi.
  • pop() - oxiridan elementni olib tashlaydi va qaytaradi.
  • shift() - boshlanishdan elementni olib tashlaydi va qaytaradi.
  • unshift(...items) - boshlanishga element qo'shadi.

Elementlarni tsikl orqali aylantirish:

  • for (let i=0; i<arr.length; i++) – eng tezkor, eski brauzerlar bilan mos keladi.
  • for (let item of arr) – faqat qiymatlar uchun zamonaviy sintaksis,
  • for (let i in arr) – ishlatmang.

Massivlarni solishtirish uchun == operatoridan foydalanmang (shuningdek, >, < va boshqalar), chunki ular massivlarga maxsus ishlov bermaydi. Ular ularni har qanday obyektlar kabi ishlatadi, bu biz odatda xohlamaymiz.

Buning o'rniga, massivlarni item-bo'yicha solishtiring yoki keyingi bo'limda tushuntirilgan iteratsiya metodlaridan foydalaning.

Kelayotgan bo'limda biz massivlar va ularga qo'shish, olib tashlash, ajratish va saralash metodlarini o'rganamiz.

Ushbu sahifada

GitHubda tahrirlash