Объекттер сап баскычтары менен маалыматтарды сактоого мүмкүндүк берет. Бул укмуш.
Бирок көп учурда биз 1-, 2-, 3-элементтерди жана башкаларды камтыган маалыматтардын иреттүү жыйнагы керектигин түшүнөбүз. Мисалы, бизге бир нерсенин тизмесин сактоо үчүн керек болот: колдонуучулар, өнүмдөр, HTML элементтери ж.б.
Бул учурда объектти колдонуу ыңгайсыз, анткени ал элементтердин тартибин көзөмөлдөө ыкмаларын камсыз кылбайт. Биз жаңы касиетти учурдагылардын "арасына" киргизе албайбыз. Объекттер жөн гана бул максат үчүн иштелип чыккан эмес.
Заказдалган коллекцияларды сактоо үчүн массив деп аталган атайын маалымат структурасы бар Array
.
Жарыя
Бош массивди түзүү үчүн эки синтаксис варианты бар:
@A@let arr = new Array();
let arr = [];@A@
Экинчи синтаксис дээрлик дайыма колдонулат. кашаанын ичинде, биз элементтердин баштапкы маанилерин көрсөтө алабыз:
@A@let fruits = ["Яблоко", "Апельсин", "Слива"];@A@
Массивдин элементтери нөлдөн баштап номерленет.
Чарчы кашаанын ичинде анын номерин көрсөтүү менен элементти ала алабыз:
@A@let fruits = ["Яблоко", "Апельсин", "Слива"];
alert( fruits[0] ); // Яблоко
alert( fruits[1] ); // Апельсин
alert( fruits[2] ); // Слива@A@
Биз элементти алмаштыра алабыз:
@A@fruits[2] = 'Груша'; // теперь ["Яблоко", "Апельсин", "Груша"]@A@
...Же учурдагы массивге жаңысын кошуңуз:
@A@fruits[3] = 'Лимон'; // теперь ["Яблоко", "Апельсин", "Груша", "Лимон"]@A@
Массив элементтеринин жалпы саны анын касиетинде камтылган length
:
@A@let fruits = ["Яблоко", "Апельсин", "Слива"];
alert( fruits.length ); // 3@A@
Сиз колдонуп бүт массивди көрсөтө аласыз alert
.
@A@let fruits = ["Яблоко", "Апельсин", "Слива"];
alert( fruits ); // Яблоко, Апельсин, Слива@A@
Массив ар кандай типтеги элементтерди камтышы мүмкүн.
Мисалы:
@A@// разные типы значений
let arr = [ 'Яблоко', { name: 'Джон' }, true, function() { alert('привет'); } ];
// получить элемент с индексом 1 (объект) и затем показать его свойство
alert( arr[1].name ); // Джон
// получить элемент с индексом 3 (функция) и выполнить её
arr[3](); // привет@A@
Объект касиеттеринин тизмеси сыяктуу массив элементтеринин тизмеси үтүр менен аякташы мүмкүн:
@A@let fruits = [
"Яблоко",
"Апельсин",
"Слива",
];@A@
Арткы үтүр элементтерди кошуу/алып салуу процессин жөнөкөйлөтөт, анткени бардык саптар бирдей болуп калат.
"at" менен акыркы элементтерди алуу
Биз массивдин акыркы элементин каалайбыз дейли.
Кээ бир программалоо тилдери терс индекстерди бир эле максатта колдонууга мүмкүндүк берет, мисалы: fruits[-1]
.
Бирок, JavaScript-те мындай белги иштебейт. Анын натыйжасы болот undefined
, анткени чарчы кашаадагы индекс түз мааниде алынган.
Биз акыркы элементтин индексин так эсептеп, анан ага төмөнкүдөй кире алабыз: fruits[fruits.length - 1]
.
@A@let fruits = ["Apple", "Orange", "Plum"];
alert( fruits[fruits.length-1] ); // Plum@A@
Бир аз түйшүктүү, туурабы? Биз өзгөрмө атын эки жолу жазышыбыз керек.
Бактыга жараша, кыскараак синтаксис бар: fruits.at (-1)
:
@A@let fruits = ["Apple", "Orange", "Plum"];
// то же самое, что и fruits[fruits.length-1]
alert( fruits.at(-1) ); // Plum@A@
Башка сөз менен айтканда arr.at(i)
,:
arr[i]
так эле окшошi >= 0
.- терс маанилер үчүн
i
массивдин аягынан чегинүүгө болот.
поп/түртүү, которуу/которуу ыкмалары
Кезек массивди эң көп колдонуу учурларынын бири. Информатикада бул операциялардын эки түрүн колдогон элементтердин иреттелген жыйнагы:
push
аягына элементти кошот.shift
башында элементти алып салып, экинчи элемент биринчи болушу үчүн кезекти жылдырат
Массивдер эки операцияны тең колдойт.
Иш жүзүндө, бул көп учурда керек. Мисалы, экранда көрсөтүлө турган билдирүүлөрдүн кезеги.
Массивдер үчүн дагы бир колдонуу учуру бар, стек деп аталган маалымат структурасы .
Ал операциялардын эки түрүн колдойт:
push
аягына элементти кошот.pop
акыркы элементти жок кылат.
Ошентип, жаңы элементтер ар дайым кошулат же "аягына" алынып салынат.
Стектин мисалы катары, адатта, карталардын палубасын айтсак болот: жаңы карталар үстүнө жайгаштырылат, ошондой эле жогорудан алынат:
JavaScript'теги массивдер кезек да, стек катары да иштей алат. Биз элементтерди массивдин башына да, аягына да кошо/алып салса болот.
Информатикада муну мүмкүн кылган маалымат структурасы деке деп аталат .
Массивдин аягы менен иштеген методдор:
pop
Массивден акыркы элементти алып салып, аны кайтарат:
@A@let fruits = ["Яблоко", "Апельсин", "Груша"];
alert( fruits.pop() ); // удаляем "Груша" и выводим его
alert( fruits ); // Яблоко, Апельсин@A@
Жана массивдин акыркы элементин кайтарат, бирок fruits.pop()
аны алып салуу менен массивди өзгөртөт.fruits.at(-1)
fruits.pop()
push
Массивдин аягына элемент кошот:
@A@let fruits = ["Яблоко", "Апельсин"];
fruits.push("Груша");
alert( fruits ); // Яблоко, Апельсин, Груша@A@
Чакыруу fruits.push(...)
эквиваленттүү fruits[fruits.length] = ...
.
Массивдин башталышы менен иштеген методдор:
shift
Массивден биринчи элементти алып салат жана аны кайтарат:
@A@let fruits = ["Яблоко", "Апельсин", "Груша"];
alert( fruits.shift() ); // удаляем Яблоко и выводим его
alert( fruits ); // Апельсин, Груша@A@
unshift
Массивдин башына элемент кошот:
@A@let fruits = ["Апельсин", "Груша"];
fruits.unshift('Яблоко');
alert( fruits ); // Яблоко, Апельсин, Груша@A@
Методдор push
жана unshift
бир эле учурда бир нече элементтерди кошууга болот:
@Alet fruits = ["Яблоко"];
fruits.push("Апельсин", "Груша");
fruits.unshift("Ананас", "Лимон");
// ["Ананас", "Лимон", "Яблоко", "Апельсин", "Груша"]
alert( fruits );@A@
Массивдин ички түзүлүштөрү
Массив - бул объекттердин өзгөчө чакан жыйындысы. Менчикке кирүү үчүн колдонулган чарчы кашаалар arr[0]
кадимки ачкыч кирүү синтаксиси болуп саналат, мисалы , бул жерде obj[key]
ролу , ал эми ачкыч сандык индекс.obj
arr
Массивдер маалыматтардын иреттелген жыйнактары менен иштөө үчүн атайын ыкмаларды, ошондой эле length
. Бирок объект дагы эле негиз болуп саналат.
JavaScriptде 8 негизги маалымат түрү бар экенин унутпаңыз. Массив объект болуп саналат, ошондуктан өзүн объект сыяктуу алып жүрөт.
Мисалы, шилтемеден көчүрүлгөн:
@A@let fruits = ["Банан"]
let arr = fruits; // копируется по ссылке (две переменные ссылаются на один и тот же массив)
alert( arr === fruits ); // true
arr.push("Груша"); // массив меняется по ссылке
alert( fruits ); // Банан, Груша - теперь два элемента@A@
...Бирок массивдерди өзгөчө кылган нерсе - бул алардын ички көрүнүшү. JavaScript кыймылдаткычы бул бөлүмдөгү сүрөттөрдө көрсөтүлгөндөй, массивдин элементтерин биринин артынан бири эс тутумдун чектеш аймагында сактоого аракет кылат. Массивдерди абдан тез кылган башка оптималдаштыруулар бар.
Бирок массивди “маалыматтардын иреттелген жыйнагы” катары кароону токтотуп, аны кадимки объект катары колдоно баштасак, алардын баары эффективдүүлүгүн жоготот.
Мисалы, техникалык жактан биз төмөнкүлөрдү жасай алабыз:
@A@let fruits = []; // создаём массив
fruits[99999] = 5; // создаём свойство с индексом, намного превышающим длину массива
fruits.age = 25; // создаём свойство с произвольным именем@A@
Бул массив объектке негизделгендиктен мүмкүн. Биз ага кандайдыр бир касиеттерди дайындай алабыз.
Бирок кыймылдаткыч биз кадимки объект сыяктуу массив менен иштеп жатканыбызды түшүнөт. Массивдер үчүн колдонулган оптималдаштыруу ыкмалары бул учурда ылайыктуу эмес, ошондуктан алар өчүрүлөт жана эч кандай пайда алып келбейт.
Массивди туура эмес колдонуунун варианттары:
- Сандык эмес касиетти кошуу, мисалы:
arr.test = 5
. - "Тешиктерди" түзүү, мисалы: кошуу
arr[0]
, андан кийинarr[1000]
(арасында эч нерсе жок). - Массивди тескери тартипте толтуруу, мисалы :
arr[1000]
ж.б.arr[999]
Массивди иреттелген маалыматтар менен иштөөгө мүмкүндүк берген атайын структура катары кароо керек . Массивдер бул үчүн атайын ыкмаларды берет. Массивдер JavaScript кыймылдаткычтарында бир эле иреттелген берилиштер менен иштөө үчүн кылдаттык менен туураланган, андыктан аларды ушундай учурларда колдонуңуз. Эгер сизге ыктыярдуу ачкычтар керек болсо, анда кадимки {}
.
Натыйжалуулук
Методдор push/pop
тез, методдор shift/unshift
жай.
Эмне үчүн массивдин башына караганда аягы менен иштөө тезирээк? Келгиле, иштөө убагында эмне болорун карап көрөлү:
fruits.shift(); // удаляем первый элемент с начала
Номери бар элементти алып салуу жана алып салуу жетиштүү эмес 0
. Ошондой эле калган элементтерди кайра номерлөө керек.
Операция shift
3 аракетти аткарышы керек:
- Индекстеги элементти алып салуу
0
. - Бардык элементтерди солго жылдыруу, аларды кайра номерлөө, аларды , менен
1
алмаштыруу ж.б.0
2
1
- Менчикти жаңыртуу
length
.
Массив канчалык көп элементтерди камтыса, аларды жылдыруу үчүн ошончолук көп убакыт талап кылынат, ошончолук көп эс тутум операциялары.
Ошол эле нерсе менен болот unshift
: массивдин башына элемент кошуу үчүн, адегенде бар элементтерди индекстерин көбөйтүү менен оңго жылдырышыбыз керек.
Бирок эмне жөнүндө push/pop
? Аларга эч нерсени жылдыруунун кереги жок. Массивдин аягындагы элементти алып салуу үчүн, метод pop
индексти тазалайт жана length
.
Операция кадамдары pop
:
fruits.pop(); // удаляем один элемент с конца
Методpop
көчүрүүнү талап кылбайт, анткени калган элементтер ошол эле индекстерде калат. Ошондуктан ал абдан тез иштейт.
Метод ушундай эле иштейт push
.
Элементтер боюнча кайталоо
Массивдин элементтерин итерациялоонун эң эски жолдорунун бири бул сандык индекстердин үстүнөн for цикли:
@A@let arr = ["Яблоко", "Апельсин", "Груша"];
for (let i = 0; i < arr.length; i++) {
alert( arr[i] );
}@A@
Бирок массивдер үчүн циклдин башка версиясы да мүмкүн, for..of
:
@A@let fruits = ["Яблоко", "Апельсин", "Слива"];
// проходит по значениям
for (let fruit of fruits) {
alert( fruit );
}@A@
Цикл for..of
учурдагы элементтин санына жетүүнү камсыз кылбайт, анын маанисине гана жетүүнү камсыз кылат, бирок көпчүлүк учурда бул жетиштүү. Жана ошондой эле кыскараак.
Техникалык жактан массив объект болгондуктан, сиз дагы вариантты колдоно аласыз for..in
:
@A@let arr = ["Яблоко", "Апельсин", "Груша"];
for (let key in arr) {
alert( arr[key] ); // Яблоко, Апельсин, Груша
}@A@
Бирок, чынында, бул жаман идея. Бул ыкманын жашыруун кемчиликтери бар:
-
Цикл объекттин сандык касиеттерин эле эмес, бардык касиеттерин
for..in
кайталайт .Браузерде жана башка программалоо чөйрөлөрүндө "псевдо-массивдер" деп аталгандар да бар - массивге окшош объекттер . Башкача айтканда, алардын касиеттери
length
жана индекстери бар, бирок алар бизге адатта кереги жок кошумча сандык эмес касиеттерге жана ыкмаларга ээ болушу мүмкүн. Бирок, циклfor..in
аларды да чыгарат. Ошондуктан, массивге окшош объектилер менен күрөшүүгө туура келсе, мындай "кошумча" касиеттер көйгөйгө айланышы мүмкүн. -
Цикл
for..in
массивдер үчүн эмес, ыктыярдуу объекттер үчүн оптималдаштырылган, ошондуктан 10-100 эсе жайыраак. Аткаруу ылдамдыгын жогорулатуу тоскоолдуктар пайда болгондо гана өзгөрүшү мүмкүн. Бирок биз дагы эле өзгөрүшүбүз керек.
for..in
Жалпысынан, массивдер үчүн циклди колдонбошуңуз керек .
"Узундук" жөнүндө бир аз
Массив өзгөргөндө, касиет length
автоматтык түрдө жаңыланат. Тактап айтканда, бул массив элементтеринин саны эмес, эң чоң санариптик индекс плюс бир.
Мисалы, чоң индекси бар бир элемент чоң узундукту берет:
@A@let fruits = [];
fruits[123] = "Яблоко";
alert( fruits.length ); // 124@A@
Көңүл буруңуз, биз адатта массивдерди мындай жол менен колдонбойбуз.
Мүлк жөнүндө дагы бир кызыктуу факт, length
анын үстүнөн жазыла тургандыгы.
Кол менен көбөйтсөк, кызык эч нерсе болбойт. Бирок биз аны азайтсак, массив кыскарат. Бул процесс артка кайтарылгыс, муну биз мисалдан түшүнөбүз:
@A@let arr = [1, 2, 3, 4, 5];
arr.length = 2; // укорачиваем до двух элементов
alert( arr ); // [1, 2]
arr.length = 5; // возвращаем length как было
alert( arr[3] ); // undefined: значения не восстановились@A@
Ошентип, массивди тазалоонун эң оңой жолу arr.length = 0;
.
newArray()
Массивди түзүү үчүн дагы бир синтаксис бар:
@A@let arr = new Array("Яблоко", "Груша", "и тд");@A@
Ал сейрек колдонулат, анткени чарчы кашаалар []
кыскараак. Мындан тышкары, анын бир татаал өзгөчөлүгү бар.
Эгер new Array
бир аргумент менен чакырылса, бул сан, ал эч кандай элементтери жок, бирок берилген узундуктагы массивди түзөт .
Келиңиз, өзүңүзгө кантип жамандык кыла аларыңызды карап көрөлү:
@A@let arr = new Array(2); // создастся ли массив [2]?
alert( arr[0] ); // undefined! нет элементов.
alert( arr.length ); // length @A@
Көрүнүп тургандай, жогорудагы коддо new Array(number)
бардык элементтер ге барабар undefined
.
Мындай күтүлбөгөн жагдайлардан качуу үчүн, биз, албетте, кандайдыр бир себептерден улам эмне керек экенин так билбесек, биз көбүнчө чарчы кашааларды колдонобуз Array
.
Көп өлчөмдүү массивдер
Массивдер массив болуп саналган элементтерди камтышы мүмкүн. Бул көп өлчөмдүү массивдерди түзүү үчүн колдонулушу мүмкүн, мисалы, матрицаларды сактоо үчүн:
@A@let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
alert( matrix[1][1] ); // 5, центральный элемент@A@
toString
Массивдер элементтердин үтүр менен бөлүнгөн тизмесин кайтарган методду өз алдынча ишке ашырат .
Мисалы:
@A@let arr = [1, 2, 3];
alert( arr ); // 1,2,3
alert( String(arr) === '1,2,3' ); // true@A@
Эми төмөндөгүлөрдү сынап көрөлү:
@A@alert( [] + 1 ); // "1"
alert( [1] + 1 ); // "11"
alert( [1,2] + 1 ); // "1,21"@A@
Symbol.toPrimitive
Массивдердин бир да функциясы жок valueOf
, алар трансформацияны гана ишке ашырышат toString
, ошондуктан бул жерде []
бош сапка айланат, [1]
болуп калат "1"
жана .[1,2]
"1,2"
Экилик плюс оператору "+"
сапка бир нерсе кошкондо, ал аны сапка да которот, ошентип:
@A@alert( "" + 1 ); // "1"
alert( "1" + 1 ); // "11"
alert( "1,2" + 1 ); // "1,21"@A@
Массивдерди == менен салыштырбаңыз
JavaScript'те, кээ бир башка программалоо тилдеринен айырмаланып, массивдерди ==
.
Бул оператордун массивдерге өзгөчө мамилеси жок, ал башка объекттердегидей эле алар менен иштейт.
Келгиле, эрежелерди кайра карап чыгалы:
==
Эки объект бир эле объектке кайрылса гана бири-бирине барабар .- Эгерде аргументтердин бири объект болсо, экинчиси примитив болсо, анда Объекттерди примитивдерге айландыруу
==
бөлүмүндө сүрөттөлгөндөй, объект примитивге айландырылат . - … Бири-бирине барабар болгон
null
жана башка эч нерседен башкасы.undefined
==
Катуу теңдик оператору ===
дагы жөнөкөй, анткени ал түрлөрдү өзгөртпөйт.
Ошентип, эгерде биз массивдерди менен салыштырсак ==
, анда биз бир массивге тиешелүү эки өзгөрмөлөрдү салыштырмайынча, алар эч качан бирдей болбойт.
Мисалы:
@A@alert( [] == [] ); // false
alert( [0] == [0] ); // false@A@
Техникалык жактан бул массивдер ар кандай объектилер. Ошентип, алар бирдей эмес. Оператор ==
элемент-элемент боюнча салыштырууну жүргүзбөйт.
Примитивдер менен салыштыруу да кызыктай көрүнгөн натыйжаларды бере алат:
@A@alert( 0 == [] ); // true
alert('0' == [] ); // false@A@
Бул жерде эки учурда тең примитивди массив объектиси менен салыштырып жатабыз. Ошентип, массив []
салыштыруу максатында примитивге айландырылат жана бош сапка айланат ''
.
Андан кийин примитивдер менен салыштыруу процесси Типти өзгөртүү бөлүмүндө баяндалгандай уланат :
@A@// после того, как [] был преобразован в ''
alert( 0 == '' ); // true, так как '' преобразуется в число 0
alert('0' == '' ); // false, нет преобразования типов, разные строки@A@
Анда массивдерди кантип салыштырасыз?
Бул жөнөкөй: колдонбоңуз ==
. Анын ордуна, циклдин элементтери боюнча аларды салыштырыңыз же кийинки бөлүмдө сүрөттөлгөн итерация ыкмаларын колдонуңуз.
Бардыгы
Массив - элементтердин иреттелген топтому менен иштөөгө арналган объекттин өзгөчө түрү.
Жарыя:
@A@// квадратные скобки (обычно)
let arr = [item1, item2...];
// new Array (очень редко)
let arr = new Array(item1, item2...);@A@
Чалуу new Array(number)
берилген узундуктагы, бирок элементтери жок массивди түзөт.
- Мүлк
length
массивдин узундугун, тагыраак айтканда, анын акыркы сандык индексин плюс бирди чагылдырат. Узундук массив ыкмалары менен автоматтык түрдө жөнгө салынат. - Кол менен азайтсак
length
, массив кыскартылат.
Элементтерди алуу:
- Биз анын индекси боюнча элементти ала алабыз, мисалы
arr[0]
. at(i)
Ошондой эле биз терс индекси бар элементтерди алуу ыкмасын колдонсок болот , терс маанилер үчүнi
ал массивдин аягынан чегинет.arr[i]
Болбосо, ал сыяктуу эле иштейтi >= 0
.
Төмөнкү операцияларды колдонуп, массивди деке катары колдоно алабыз:
push(...items)
items
массивдин аягына кошумчалайт .pop()
массивдин аягындагы элементти жок кылат жана аны кайтарат.shift()
массивдин башындагы элементти жок кылат жана аны кайтарат.unshift(...items)
items
массивдин башына кошумчалайт .
Массивдин элементтерин кайталоо үчүн:
for (let i=0; i<arr.length; i++)
– эң ылдам иштейт, эски браузерлер менен шайкеш келет.for (let item of arr)
- элементтердин баалуулуктары үчүн гана заманбап синтаксис (индекстерге жетүү мүмкүн эмес).for (let i in arr)
- массивдер үчүн эч качан колдонбоңуз!
Биз массивдерге кайрылып, кошуу, алып салуу, элементтерди чыгаруу жана массивдерди сорттоо боюнча башка ыкмаларды изилдейбиз: Массив методдору .
Tasks
Төмөнкү код эмнени чыгарат?
@A@let fruits = ["Яблоки", "Груша", "Апельсин"];
// добавляем новое значение в "копию"
let shoppingCart = fruits;
shoppingCart.push("Банан");
// что в fruits?
alert( fruits.length ); // ?@A@
Массивде 5 операция жасайлы.
- "Джаз" жана "Блюз" элементтери менен массив түзүңүз
styles
. - Аягына "Рок-н-роллду" кошуңуз.
- Ортодогу маанини Classic кылып өзгөртүңүз. Ортодогу маанини табуу үчүн кодуңуз каалаган узундуктагы массивдер үчүн иштеши керек.
- Массивдин биринчи элементин алып салыңыз жана аны көрсөтүңүз.
- Кыстаруу
Рэп
жанаРегги
массивдин башында.
Операциялар аткарылып жаткан массив:
Джаз, Блюз
Джаз, Блюз, Рок-н-ролл
Джаз, Классика, Рок-н-ролл
Классика, Рок-н-ролл
Рэп, Регги, Классика, Рок-н-ролл
натыйжасы кандай? Неге?
@A@let arr = ["a", "b"];
arr.push(function() {
alert( this );
});
arr[2](); // ?@A@
Функцияны жазыңыз sumInput()
:
- Колдонуучудан баалуулуктарды киргизүүнү суранат
prompt
жана аларды массивде сактайт. - Колдонуучу сандык эмес маанини, бош сапты киргизгенде же "Жокко чыгаруу" баскычын чыкылдатканда, маанилерди суроону токтотот.
- Массивдин элементтеринин суммасын санайт жана кайтарат.
PS Zero 0
сан болуп эсептелет, "0" киргизүүдө маанилерди киргизүүнү токтотпоңуз.
Киргизүү сандар массивинен турат, мисалы: arr = [1, -2, 3, 4, -9, 6]
.
arr
Тапшырма: элементтеринин суммасы максималдуу болгон үзгүлтүксүз кичи массивди табыңыз .
Функция getMaxSubSum(arr)
бул сумманы кайтарышы керек.
Мисалы:
getMaxSubSum([-1, 2, 3, -9]) == 5 (сумма выделенных элементов)
getMaxSubSum([2, -1, 2, 3, -9]) == 6
getMaxSubSum([-1, 2, 3, -9, 11]) == 11
getMaxSubSum([-2, -1, 1, 2]) == 3
getMaxSubSum([100, -9, 2, -3, 5]) == 100
getMaxSubSum([1, 2, 3]) == 6 (берём все)@A@
Эгерде бардык элементтер терс болсо, биз эч нерсе албайбыз (кошумча массив бош) жана сумма "0" болот:
getMaxSubSum([-1, -2, -3]) = 0
Тез чечим табууга аракет кылыңыз: O(n 2 ) , же O(n) операцияларында жакшыраак.