Як змінити елементи масиву за умовою?
Завдання полягає в тому, що потрібно змінити певні значення в масиві за умовою, тобто, наприклад якщо якийсь елемент масиву дорівнює 1000 тоді замінюємо його значення на "1К +" і так далі. Здавалося б завдання просте, але спроба вирішити її подібним чином:
let arr = [1000, 2005, 600, 4000, 5000]; let newArray = []; arr.forEach(n => < switch (true) < case n >999: n = "1К +"; case n > 2000: n = "2К +"; case n > 4000: n = "4К +"; case n > 5000: n = "5К +"; > newArray.push(n); console.log(newArray);
["5К +", "5К +", 600, "5К +", "5К +"]
Тобто перша і друга умова ігнорується, і виконується остання. Виходить, що елементи масиву, значення яких вище 999, отримують оновлені значення, рівні = 5000(5К+) , але це неправильно, так як наприклад 1000 повинен бути оновлений таким значенням = 1К + . Потрібний результат має виглядати так:
["1К +", "2К +", 600, "4К +", "5К +"]
Спроба додавати break у case, не дає жодних позитивних результатів. Умов може бути багато, тому вибрав switch замість if else для збереження читання коду. Але навіть якщо пожертвувати читання коду і спробувати переписати на if else if else, або if(), if(), if() то все одно ніякого потрібного результату не буде. Чи є якийсь спосіб це вирішити?
Array.prototype.splice()
Ця особливість є добре створеною і роботою, пов'язаною з багатьма пристроями і розробниками версій. It's been available across browsers since July 2015 .
Зведення
Метод splice() змінює вміст масиву, видаляючи існуючі елементи та/або додаючи нові.
Синтаксис
array.splice(start[, deleteCount[, item1[, item2[, . ]]]])
Параметри
Індекс, яким починає змінювати масив. Якщо більша довжина масиву, реальний індекс буде встановлений на довжину масиву.Якщо негативний, індекс індексу вказує з кінця.
Ціле число, що показує кількість старих елементів, що видаляються з масиву. Якщо deleteCount дорівнює 0, елементи не видаляються. У цьому випадку ви повинні вказати щонайменше один новий елемент. Якщо deleteCount більше кількості елементів, що залишилися в масиві, починаючи з індексу start, будуть видалені всі елементи до кінця масиву.
Необов'язкові параметри. Елементи, що додаються до масиву. Якщо ви не вкажете елемент, splice() просто видаляє елементи з масиву.
Значення, що повертається
Масив, що містить видалені елементи. Якщо видалено лише один елемент, повернеться масив з одного елемента. Якщо елементи не видаляються, повернеться порожній масив.
Опис
Якщо кількість вказаних елементів буде відмінною від кількості елементів, що видаляються, масив змінить довжину після виклику.
Приклади
Видаляє 0 елементів за індексом 2 та вставляє "drum"
var myFish = ["angel", "clown", "mandarin", "sturgeon"]; var removed = myFish.splice(2, 0, "drum"); // myFish дорівнює ["angel", "clown", "drum", "mandarin", "sturgeon"] // removed дорівнює [], нічого не видалено
Видаляє 1 елемент за індексом 3
var myFish = ["angel", "clown", "drum", "mandarin", "sturgeon"]; var removed = myFish.splice(3, 1); // removed дорівнює ["mandarin"] // myFish дорівнює ["angel", "clown", "drum", "sturgeon"]
Видаляє 1 елемент індексу 2 і вставляє "trumpet"
var myFish = ["angel", "clown", "drum", "sturgeon"]; var removed = myFish.splice(2, 1, "trumpet"); // myFish дорівнює ["angel", "clown", "trumpet", "sturgeon"] // removed дорівнює ["drum"]
Видаляє 2 елементи починаючи з індексу 0 і вставляє "parrot", "anemone" та "blue"
var myFish = ["angel", "clown", "trumpet", "sturgeon"]; var removed = myFish.splice(0, 2, "parrot", "anemone", "blue"); // myFish дорівнює ["parrot", "anemone", "blue", "trumpet", "sturgeon"] // removed дорівнює ["angel", "clown"]
Видаляє 2 елементи, починаючи з індексу 2
var myFish = ["parrot", "anemone", "blue", "trumpet", "sturgeon"]; var removed = myFish.splice(myFish.length - 3, 2); // myFish дорівнює ["parrot", "anemone", "sturgeon"] // removed дорівнює ["blue", "trumpet"]
Видаляє 1 елемент за індексом -2
var myFish = ["angel", "clown", "mandarin", "sturgeon"]; var removed = myFish.splice(-2, 1); // myFish дорівнює ["angel", "clown", "sturgeon"] // removed дорівнює s ["mandarin"]
Видаляє всі елементи після індексу 2 (включно)
var myFish = ["angel", "clown", "mandarin", "sturgeon"]; var removed = myFish.splice(2); // myFish дорівнює ["angel", "clown"] // removed дорівнює ["mandarin", "sturgeon"]
Специфікації
Сумісність із браузерами
BCD tables only load in the browser
Зворотна сумісність
У JavaScript 1.2 метод splice() повертав віддалений елемент тільки якщо був вилучений один елемент (параметр deleteCount дорівнює 1); інакше метод повертав масив з віддаленими елементами. Зверніть увагу, що останнім браузером, що використовує JavaScript 1.2, був Netscape Navigator 4, тому ви можете вважати, що splice() завжди повертає масив.
Дивіться також
- push() / pop() — додавання/видалення елементів з кінця масиву
- unshift() / shift() — додавання/видалення елементів з початку масиву
- concat() — повертає новий масив, що складається з даного масиву, з'єднаного з іншими масивами та/або значеннями
Масиви
Об'єкти дозволяють зберігати дані з рядковими ключами. Це чудово.
Але досить часто ми розуміємо, що нам потрібна впорядкована колекція даних, у яких присутні 1-й, 2-й, 3-й елементи і т.д. Наприклад, вона знадобиться нам для зберігання списку чогось: користувачів, товарів, елементів HTML тощо.
І тут використовувати об'єкт незручно, оскільки він надає методів управління порядком елементів. Ми не можемо вставити нову властивість «між» вже існуючими. Об'єкти просто не призначені для цього.
Для зберігання впорядкованих колекцій існує особлива структура даних, яка називається масив Array .
Оголошення
Існує два варіанти синтаксису для створення порожнього масиву:
let arr = новий Array(); let arr = [];
Практично завжди використовується другий варіант синтаксису. У дужках ми можемо вказати початкові значення елементів:
let fruits = ["Яблуко", "Апельсин", "Слива"];
Елементи масиву нумеруються, починаючи з нуля.
Ми можемо отримати елемент, вказавши його номер у квадратних дужках:
let fruits = ["Яблуко", "Апельсин", "Слива"]; alert( fruits[0] ); // Яблуко alert( fruits[1] ); // Апельсин alert( fruits[2] ); // Слива
Ми можемо замінити елемент:
fruits[2] = 'Груша'; // тепер ["Яблуко", "Апельсин", "Груша"]
…Або додати новий до існуючого масиву:
fruits[3] = 'Лимон'; // тепер ["Яблуко", "Апельсин", "Груша", "Лимон"]
Загальна кількість елементів масиву міститься у його властивості length :
let fruits = ["Яблуко", "Апельсин", "Слива"]; alert( fruits.length ); // 3
Вивести масив цілком можна за допомогою alert.
let fruits = ["Яблуко", "Апельсин", "Слива"]; alert (fruts); // Яблуко, Апельсин, Слива
У масиві можуть зберігатися елементи будь-якого типу.
// різні типи значень let arr = [ 'Яблуко', < name: 'Джон' >, true, function() < alert('привіт'); >]; // Отримати елемент з індексом 1 (об'єкт) і потім показати його властивість alert(arr[1].name); // Джон // одержати елемент із індексом 3 (функція) і здійснити її arr[3](); // привіт
Список елементів масиву, як і список властивостей об'єкта, може закінчуватися комою:
let fruits = ["Яблуко", "Апельсин", "Слива",];
«Висяча кома» спрощує процес додавання/видалення елементів, оскільки всі рядки стають ідентичними.
Отримання останніх елементів за допомогою at
Ця можливість була додана в мову нещодавно. У старих браузерах може знадобитися поліфіл.
Припустимо, нам потрібний останній елемент масиву.
Деякі мови програмування дозволяють використовувати негативні індекси для тієї ж мети якось так: fruits[-1] .
Однак у JavaScript такий запис не спрацює. Її результатом буде undefined, оскільки індекс у квадратних дужках розуміється буквально.
Ми можемо явно обчислити індекс останнього елемента, а потім отримати доступ до нього ось так: fruits[fruits.length - 1] .
let fruits = ["Apple", "Orange", "Plum"]; alert (fruits [fruits.length-1]); // Plum
Трохи громіздко, чи не так? Нам потрібно двічі написати ім'я змінної.
На щастя, є коротший синтаксис: fruits.at(-1) :
let fruits = ["Apple", "Orange", "Plum"]; // те саме, як і fruits[fruits.length-1] alert( fruits.at(-1) ); // Plum
Іншими словами, arr.at(i) :
- це рівно те саме, що й arr[i] , якщо i >= 0 .
- для негативних значень i він відступає від кінця масиву.
Методи pop/push, shift/unshift
Черга – один із найпоширеніших варіантів застосування масиву.У галузі комп'ютерних наук так називається впорядкована колекція елементів, що підтримує два види операцій:
- push додає елемент до кінця.
- shift видаляє елемент спочатку, зрушуючи чергу, так що другий елемент стає першим.
Масиви підтримують обидві операції.
Насправді необхідність у цьому виникає дуже часто. Наприклад, черга повідомлень, які потрібно показати на екрані.
Існує й інший варіант застосування масивів – структура даних, звана стек.
Вона підтримує два види операцій:
- push додає елемент до кінця.
- pop видаляє останній елемент.
Таким чином, нові елементи завжди додаються або видаляються з кінця.
Прикладом стека зазвичай служить колода карт: нові карти кладуться нагору і теж беруться зверху:
Масиви JavaScript можуть працювати і як черга, і як стек. Ми можемо додавати/видаляти елементи як на початок, так і в кінець масиву.
У комп'ютерних науках структура даних, що робить це можливим, називається двостороння черга.
Методи, що працюють з кінцем масиву:
Видаляє останній елемент з масиву та повертає його:
let fruits = ["Яблуко", "Апельсин", "Груша"]; alert( fruits.pop() ); // видаляємо " Груша " і виводимо його alert( fruits ); // Яблуко, Апельсин
І fruits.pop() і fruits.at(-1) повертають останній елемент масиву, але fruits.pop() також змінює масив, видаляючи його.
Додає елемент до кінця масиву:
let fruits = ["Яблуко", "Апельсин"]; fruits.push("Груша"); alert (fruts); // Яблуко, Апельсин, Груша
Виклик fruits.push(. ) рівнозначний fruits[fruits.length] = . .
Методи, що працюють із початком масиву:
Видаляє з масиву перший елемент і повертає його:
let fruits = ["Яблуко", "Апельсин", "Груша"];
Додає елемент на початок масиву:
let fruits = ["Апельсин", "Груша"];
Методи push і unshift можуть додавати відразу кілька елементів:
let fruits = ["Яблуко"]; "Апельсин", "Груша"] alert (fruits);
Внутрішній пристрій масиву
Масив – це особливий підвид об'єктів. ключа – числовий індекс.
Масиви розширюють об'єкти, оскільки передбачають спеціальні методи роботи з упорядкованими колекціями даних, і навіть властивість length .
Слід пам'ятати, що JavaScript існує 8 основних типів даних. Масив є об'єктом і, отже, веде себе як об'єкт.
Наприклад, копіюється за посиланням:
let fruits = ["Банан"] let arr = fruits; // копіюється за посиланням (дві змінні посилаються на той самий масив) alert( arr === fruits ); // масив змінюється на засланні alert( fruits ); // Банан, Груша - тепер два елемента
…Але те, що дійсно робить масиви особливими – це їхнє внутрішнє уявлення. працюють дуже швидко.
Але вони втратить ефективність, якщо ми перестанемо працювати з масивом як із «упорядкованою колекцією даних» і почнемо використовувати його як звичайний об'єкт.
Наприклад, технічно ми можемо зробити таке:
let fruits = []; // Створюємо масив fruits[99999] = 5; // Створюємо властивість з індексом, набагато перевищує довжину масиву fruits.age = 25; // Створюємо властивість з довільним ім'ям
Це можливо тому, що в основі масиву лежить об'єкт. Ми можемо привласнити йому будь-які властивості.
Але двигун зрозуміє, що ми працюємо з масивом, як зі звичайним об'єктом. Способи оптимізації, які використовуються для масивів, у цьому випадку не підходять, тому вони будуть відключені і ніякої вигоди не принесуть.
Варіанти неправильного застосування масиву:
- Додавання нечислової якості, наприклад: 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 за цифровими індексами:
let arr = ["Яблуко", "Апельсин", "Груша"]; for (let i = 0; i
Але для масивів можливий інший варіант циклу, for..of :
let fruits = ["Яблуко", "Апельсин", "Слива"]; // проходить за значеннями for (let fruit of fruits)
Цикл for..of не надає доступу до номера поточного елемента, тільки його значення, але в більшості випадків цього достатньо. І це коротше.
Технічно, оскільки масив є об'єктом, можна використовувати варіант for..in :
let arr = ["Яблуко", "Апельсин", "Груша"]; for (let key in arr) <alert(arr[key]); // Яблуко, Апельсин, Груша>
Але насправді це погана ідея. Існують приховані недоліки цього способу:
- Цикл for..in виконує перебір всіх властивостей об'єкта, а не лише цифрових.У браузері та інших програмних середовищах також існують так звані «псевдомасиви» – об'єкти, які виглядають, як масив. Тобто вони мають властивість length та індекси, але вони також можуть мати додаткові нечислові властивості та методи, які нам зазвичай не потрібні. Проте, цикл for..in виведе їх. Тому якщо нам доводиться мати справу з об'єктами, схожими на масив, такі «зайві» властивості можуть стати проблемою.
- Цикл for..in оптимізований під довільні об'єкти, не масиви, і тому в 10-100 разів повільніше. Збільшення швидкості виконання може мати значення лише у разі виникнення вузьких місць. Але ми все ж таки повинні представляти різницю.
Загалом не слід використовувати цикл for..in для масивів.
Небагато про «length»
Властивість length автоматично оновлюється при зміні масиву. Якщо бути точними, це не кількість елементів масиву, а максимальний цифровий індекс плюс один.
Наприклад, єдиний елемент, що має великий індекс, дає більшу довжину:
let fruits = []; fruits[123] = "Яблуко"; alert( fruits.length ); // 124
Зверніть увагу, що зазвичай ми не використовуємо масиви таким чином.
Ще один цікавий факт про якість length – його можна перезаписати.
Якщо ми вручну збільшимо його, нічого цікавого не станеться. Проте, якщо ми зменшимо його, масив стане коротшим. Цей процес необоротний, як ми можемо зрозуміти з прикладу:
let arr = [1, 2, 3, 4, 5]; arr.length = 2; // укорочуємо до двох елементів alert(arr); // [1, 2] arr.length = 5; // Повертаємо length як було alert (arr [3]); // undefined: значення не відновилися
Таким чином, найпростіший спосіб очистити масив – це arr.length = 0; .
new Array()
Існує ще один варіант синтаксису для створення масиву:
let arr = new Array("Яблуко", "Груша", "і тд");
Він рідко застосовується, оскільки квадратні дужки [] коротші. Крім того, він має хитру особливість.
Якщо new Array викликається з одним аргументом, який є числом, він створює масив без елементів, але із заданою довжиною.
Давайте подивимося, як можна надати собі ведмежу послугу:
let arr = новий Array(2); // Чи створиться масив [2]? alert(arr[0]); // undefined! немає елементів. alert(arr.length); // Length 2
Як бачимо, у коді, представленому вище, в new Array(number) все елементи рівні undefined .
Щоб уникнути появи таких несподіваних ситуацій, ми зазвичай використовуємо квадратні дужки, якщо, звичайно, не знаємо точно, що з якоїсь причини потрібен саме Array.
Багатовимірні масиви
Масиви можуть містити елементи, які є масивами. Це можна використовувати для створення багатовимірних масивів, наприклад, для зберігання матриць:
let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; alert (matrix [1] [1]); // 5, центральний елемент
toString
Масиви по-своєму реалізують метод toString, який повертає список елементів, розділених комами.
let arr = [1, 2, 3]; alert (arr); // 1,2,3 alert(String(arr) === '1,2,3'); // true
Давайте тепер спробуємо наступне: