Контакти

Javascript проходить по масиву. Всі способи перебору масиву JavaScript. Метод forEach і споріднені методи

Стаття, в якій розглянемо приклади використання функції та методу бібліотеки jQuery each .

У бібліотеці jQuery є 2 різні сутності з назвою each.

Перша (jQuery.each) - це універсальна функція jQuery, за допомогою якої можна здійснити перебір елементів масиву або об'єкта.

Друга (each) - це метод, який застосовується до набору елементів для організації циклу за ними.

Цикл each (jQuery.each). Приклади використання

Синтаксис функції each :

// array чи object - масив чи об'єкт, елементи чи властивості якого необхідно перебрати // callback - функція, яка буде виконана кожного елемента масиву чи властивості об'єкта $.each(array чи object,callback);

Роботу з функцією each розберемо на прикладах.

Приклад №1. У ньому виконаємо перебер всіх елементів масиву (array).

// масив, що складається з 3 рядків var arr = ["Автомобіль", "Вантажівка", "Автобус"]; // переберемо масив arr $.each(arr,function(index,value)( // дії, які будуть виконуватися для кожного елемента масиву // index - це поточний індекс елемента масиву (число)) // value - це значення поточного елемента масиву //виведемо індекс та значення масиву в консоль console.log("Індекс:" + index + "; Значення: "+ value); )); /* Результат (в консолі): Індекс: 0; Значення: Автомобіль Індекс: 1; Значення: Вантажівка Індекс: 2; Значення: Автобус */

У наведеному вище коді функція each використовується для перебору масиву. Функція має 2 обов'язкові параметри. Перший параметр – це сутність (масив чи об'єкт), елементи (властивості) якої необхідно перебрати. В даному випадку - це масив arr. Другий параметр – це функція зворотного дзвінка, яка буде виконана для кожного елемента (в даному випадку) масиву. Вона має 2 параметри, які доступні всередині неї за допомогою відповідних змінних. Перший параметр – це порядковий номер елемента (відлік виконується з 0). Другий параметр – це значення поточного елемента масиву.

Приклад №2. У цьому вся прикладі здійснимо перебір всіх властивостей об'єкта.


// об'єкт smartphone, що має 5 властивостей var smartphone = ( "name": "LG G5 se", "year": "2016", "screen-size": "5.3", "screen-resolution": "2560 x 1440 ", "os": "Android 6.0 (Marshmallow)"); // переберемо об'єкт smartphone $.each(smartphone, function(key, value) ( ​​// дії, які будуть виконуватися для кожної властивості об'єкта // key - поточне ім'я властивості масиву // value - значення поточної властивості об'єкта та його значення в консоль console.log("Властивість:" +key + "; Значення: "+ value); )); /* Результат (в консолі): Властивість: name; Значення: LG G5 se Властивість: year; Значення: 2016 Властивість: screen-size; Значення: 5.3 Властивість: screen-resolution; Значення: 2560 x 1440 Властивість: os; Значення: Android 6.0 (Marshmallow) */

Функція each може використовуватися для вибору JavaScript об'єктів. Відмінність її використання у тому, що параметри функції зворотного виклику мають інші значення. Перший параметр зберігає назву якості об'єкта, а другий - значення цієї характеристики.

Приклад №3. У ньому здійснимо перебір складнішої структури (розглянемо, як використовувати вкладені each ).

/ / Об'єкт, що складається з 2 властивостей. Кожна властивість цього об'єкт має як значення масив, елементами якого є також об'єкти var articles = ("Bootstrap": [("id":"1", "title":"Введення"), ("id":"2" , "title":"Як встановити"), ("id":"3", "title":"Сітка") ], "JavaScript": [ ("id":"4", "title":"Основи "), ("id":"5", "title":"Вибірка елементів")]); $.each(articles,function(key,data) ( console.log("Розділ: " + key); $.each(data, function(index,value) ( ​​console.log("Стаття: id = " + value) ["id"] + "; Назва = "+ value["title"]); )); )); /* Результат: Розділ: Bootstrap Стаття: id = 1; Назва = Введення Стаття: id = 2; Назва = Як встановити Стаття: id = 3; Назва = Сітка Розділ: JavaScript Стаття: id = 4; Назва = Основи Стаття: id = 5; Назва = Вибірка елементів */

Як перервати each (вийти із циклу)?

Переривання (break) циклу each здійснюється за допомогою оператора return, який повинен повертати значення false.

Наприклад, перервемо виконання циклу each після того, як знайдемо в масиві arr число 7:

// масив, що з 5 чисел var arr = ; // Число, яке необхідно знайти var find = 7; // переберемо масив arr $.each(arr, function (index, value) ( ​​// якщо необхідне число знайдено, то .. if (value === find) ( // вивести його в консоль console.log("Ура!) Число "+ find +" знайдено! Дане число має індекс: "+ index); // перервати виконання циклу return false; ) else (// інакше вивести в консоль поточне число console.log("Поточне число: "+ value); ))); /* Результат (в консолі): Поточне число: 5 Поточне число: 4 Ура! Число 7 знайдено! Це число має індекс: 2 */

Як перейти до наступної ітерації (each continue)?

У всіх переривання виконання поточної ітерації і перехід до наступної здійснюється за допомогою оператора return, який повинен мати значення, відмінне від false.

// масив, що з чисел var arr = ; // масив, який має містити всі елементи масиву arr, крім парних чисел var newarr = ; // переберемо масив arr $.each(arr, function (index, value) ( ​​// якщо елемент парний, то пропустимо його if (value % 2 === 0)) ( // перервемо виконання поточної ітерації і перейдемо до наступної return; ) // додати масив newarr значення value newarr.push(value); )); console.log("Початковий масив (arr):" + arr.join()); console.log("Результуючий масив (newarr):" + newarr.join()); /* Результат (в консолі): Вихідний масив (arr): 3,5,4,9,17,19,30,35,40 Результуючий масив (newarr): 3,5,9,17,19,35 */

Перебір поточних елементів (.each)

Синтаксис методу each (змінюється лише до вибраних елементів):


.each(function); // function – функція, яка буде виконана для кожного елемента поточного об'єкта

Розберемо, як працює метод.each на наступному прикладі (переберемо елементи div):

// після завантаження DOM сторінки виконати $(function()( // перебрати елементи div на сторінці $("div")). / дане значення є числом // починається відлік з 0 і закінчується кількістю елементів у поточному наборі мінус 1 // element - містить DOM-посилання на поточний елемент console.log("Індекс елемента div:" + index + "; id елемента = " + $(element).attr("id")); )); )); // Результат: // Індекс елемента div: 0; id елемента = id1 // Індекс елемента div: 1; id елемента = id2 // Індекс елемента div: 2; id елемент = id3

У наведеному вище прикладі метод each використовує поточний набір (елементи, вибрані за допомогою селектора $("div")). Як обробник методу each завжди виступає функція, яка буде виконана для кожного елемента поточного набору (в даному випадку для кожного елемента div). Ця функція має 2 необов'язкові параметри. Один з них (index) є порядковим номером поточної ітерації, а другий (element) - DOM посилання на поточний елемент. Крім цього всередині функції доступне ключове слово this , яке також як і другий параметр містить DOM-посилання на поточний елемент.

Наприклад, виведемо в консоль значення атрибуту href для всіх елементів, а на сторінці:

$("a").each(function() ( console.log($(this).attr("href")); ));

$("a").each(function() ( var link = $(this).attr("href"); if ((link.indexOf("http://") == 0) || (link .indexOf("https://") == 0)) ( console.log("href посилання = " + link); ) ))); // Якщо на сторінці розміщені такі посилання: // Яндекс // Як працює JavaScript? // Bootstrap // То в консолі побачимо наступний результат: // https://www.yandex.ru/ // http://getbootstrap.com/

Наприклад, розглянемо, як організувати цикл each по елементам DOM, які мають клас name (переберемо всі елементи одного класу).

Raspberry pi single-board compute Intel Galileo Gen2 19$ Pine A64 Plus // за допомогою функції jQuery.each ($.each) $.each($(".name"),function(index,data) ( console.log( "Порядковий номер: " + index + "; Вміст: " +$(data).text()); )); // за допомогою методу jQuery .each $(". name"). ));)); // Отримаємо наступну відповідь: // Порядковий номер: 0; Вміст: Raspberry pi // Порядковий номер: 1; Вміст: Intel Galileo Gen2 // Порядковий номер: 2; Вміст: Pine A64 Plus

Наприклад, розберемо як перебрати всі елементи на сторінці.

$("*").each(function() ( console.log(this); ));

Наприклад, виведемо значення всіх елементів input на сторінці.

$("input").each(function() ( console.log($(this).val()); ));

Наприклад, переберемо всі дочірні елементи, які розташовані в ul з id="myList" (each children).

  • HTML
  • JavaScript
$("ul#myList").children().each(function()( console.log($(this).text()); )); // Результат: // HTML // CSS // JavaScript

Розглянемо спосіб, за допомогою якого можна визначити останній індекс (елемент) у методі jQuery each.

// Вибираємо елементи var myList = $ ("ul li"); // Визначаємо кількість елементом у вибірці var total = myList.length; // здійснюємо перебір обраних елементів myList.each(function(index) ( if (index === total - 1) ( // це останній елемент у вибірці )));

22 відповіді

Після виконання цього тесту з більшістю сучасних браузерів...

Нині найшвидша форма циклу (і, мій погляд, найбільш синтаксично очевидна).

стандарт для циклу з кешуванням за довжиною

For (var i = 0, len = myArray.length; i< len; i++) { }

Я б сказав, що це безперечно випадок, коли я вітаю розробників движка JavaScript. Час виконання має бути оптимізований для ясності, а не для зручності.

Станом на червень 2016 року, кілька тестів в останньому Chrome (71% ринку браузерів у травні 2016 року та збільшення):

  • Найшвидший цикл - це цикл циклу як з довжиною кешування, так і без нього, що забезпечує дуже схожу продуктивність. (Цикл for з кешованою довжиною іноді дає кращі результати, ніж той, що не кешується, але різниця майже незначна, а це означає, що двигун може бути оптимізований на користь стандартного і, можливо, найпростішого циклу без кешування).
  • Цикл while з декрементами був приблизно 1,5 разу повільніше, ніж цикл for.
  • Цикл з використанням функції зворотного виклику (наприклад, standard forEach) був приблизно в 10 разів повільніший, ніж цикл for.

Я вважаю, що цей потік занадто старий, і програмісти вважають, що їм потрібно кешувати довжину, або використовувати зворотні перетину зі зменшенням, щоб домогтися більшої продуктивності, написання коду, який є менш розбірливим і більш схильним до помилок, ніж простий для циклу. Тому я рекомендую:

    Якщо ваша програма повторює безліч елементів або ваш код циклу знаходиться всередині функції, яка використовується часто, прямий цикл є відповіддю:

    For (var i = 0; i< arr.length; i++) { // Do stuff with arr[i] or i }

    Якщо ваша програма дійсно не перебирає безліч елементів або вам просто потрібно робити невеликі ітерації тут і там, використання стандартного зворотного виклику forEach або будь-якої подібної функції з обраної вами бібліотеки JS може бути більш зрозумілим і менш схильний до помилок, оскільки область змінних індексу закрита, і вам не потрібно використовувати дужки, що безпосередньо звертаються до значення масиву:

    Arr.forEach(function(value, index) ( // Do stuff with value or index ));

    Якщо вам дійсно потрібно пом'яти кілька мілісекунд, ітерації по мільярдах рядків, і довжина масиву не зміниться в процесі, ви можете подумати про довжину кешування в циклі for. Хоча я думаю, що в наші дні це справді не потрібно:

    For (var i = 0, len = arr.length; i< len; i++) { // Do stuff with arr[i] }

Це просто 2018, так що оновлення може бути гарним...

І я дійсно маю не погодитися з прийнятою відповіддю. Це залежить від різних браузерів. деякі роблять forEach швидше, деякі for-loop , а деякі while тестують всі методи http://jsben.ch/mW36e

Arr.forEach(a => ( // ... )

і так як ви можете побачити безліч циклів for(a = 0;...) наприклад, for(a = 0;...) то варто згадати, що без змінних "var" буде визначатися глобально, і це може суттєво вплинути на швидкість, тому вона буде повільною.

var arr = arr = new Array(11111111).fill(255); var benches = [["empty", () =>< l; a++); }] , ["for-loop", () =>( for(var a = 0, l = arr.length; a< l; ++a) var b = arr[a] + 1; }] , ["for-loop++", () =>( for(var a = 0, l = arr.length; a< l; a++) var b = arr[a] + 1; }] , ["for-loop - arr.length", () =>( for (var a = 0; a< arr.length; ++a) var b = arr[a] + 1; }] , ["reverse for-loop", () =>( for(var a = arr.length - 1; a >= 0; --a) var b = arr[a] + 1; )] ,["while-loop", () => ( var a = 0 , l = arr.length;while(a< l) { var b = arr[a] + 1; ++a; } }] , ["reverse-do-while-loop", () =>( var a = arr.length - 1; // CAREFUL do ( var b = arr[a] + 1; ) while(a--); )] , ["forEach", () => ( arr.forEach( a => (var b = a + 1; )); )] , ["for..in (тільки 3.3%)", () => ( var ar = arr.slice(0,arr.length/33) for (const a in ar) (var b = a + 1;))], ["Duff device", () => (var i = 0; var r = arr.length % 8; var n = (arr .length - r) / 8; if (r > 0) do (var b = arr + 1;) while (--r); if (n > 0) do (var b = arr [i] + 1; c = arr + 1; var d = arr + 1; var e = arr + 1; var f = arr + 1; var g = arr + 1; var h = arr + 1; var k = arr + 1; i = --n >>> 3; ) while (n); )] , ["Duff device negative", () => ( var r = arr.length % 8; var n = (arr.length-r) / 8 ///Math.floor(arr.length / 8); var i = arr.length ; // -1; (n) (var b = arr [i] + 1; var c = arr + 1; var d = arr + 1; var e = arr + 1; var f = arr + 1; var g = arr + 1; var h = arr + 1; var j = arr + 1; i = --n >>> 3; ))]]; function bench(title, f) ( var t0 = performance.now(); var res = f(); return performance.now() - t0; // console.log("$(title) took $(t1-t0) ) msec"); ) var globalVarTime = bench("for-loop without "var"", () => ( // Тут ви знайдете "Var" з параметрами"ll be global for(a = 0, l = arr.length;< l; ++a) var b = arr[a] + 1; }); var times = benches.map(function(a) { arr = new Array(11111111).fill(255); return }).sort((a,b) =>a-b); var max = times; times = times.map(a => (a = (a/max)*100; return a; )); var template = (title, time, n) => "" + "$(title) " + " $(Number(time.toFixed(3)))msec" + ""; var strRes = times.map(t => template(...t)).join("\n") + "

for-loop без "var" $(globalVarTime) msec."; var $container = document.getElementById("container"); $container.innerHTML = strRes; body ( color:#fff; background:#333; font-family :helvetica; ) body > div > div ( clear:both ) body > div > div > span ( float:left; width:43%; margin:3px 0; text-align:right; ) body > div > div > span :nth-child(2) ( text-align:left; background:darkorange; animation:showup .37s .111s; -webkit-animation:showup .37s .111s; ) @keyframes showup ( from ( width:0; ) ) @-webkit-keyframes showup ( from ( width:0; ) )

2014 While тому

Подумайте логічно.

Подивіться на це

For(var index = 0 , length = array.length ; index< length ; index++) { //do stuff }

  • Необхідно створити щонайменше 2 змінних (індекс, довжина)
  • Необхідно перевірити, чи менший покажчик довжини
  • Необхідно збільшити індекс
  • цикл for має 3 параметри

Тепер скажіть мені, чому це має бути швидше, ніж:

Var length = array.length; while(--length) ( //or length-- //do stuff )

  • Одна змінна
  • Немає перевірок
  • індекс зменшується (машини воліють це)
  • While має лише один параметр

Я був повністю спантеличений, коли Chrome 28 показав, що цикл for працює швидше, ніж час. Це має бути якось

"Ну кожен використовує цикл for, нехай фокусується на цьому, коли для хром ".

Але тепер, у 2014 році, цикл while повертається на хром. він у 2 рази швидше, в інших/старих браузерах він завжди був швидшим.

Останнім часом я зробив кілька тестів. Тепер у реальному світі envoirement ці короткі коди нічого не варті, і jsperf не може фактично правильно виконати цикл while, тому що йому потрібно відтворити array.length, що також вимагає часу.

НЕ МОЖЕ отримати фактичну швидкість циклу, коли на jsperf.

вам потрібно створити свою власну функцію та перевірити, що за допомогою window.performance.now()

І так... немає ніякого способу, щоб цикл while був швидше.

Реальна проблема - це фактичне маніпулювання/час відтворення/час малювання або ви хочете називати його.

Наприклад, у мене є сцена canvas, де мені потрібно обчислити координати та колізії... це робиться між 10-200 MicroSeconds (не мілісекундами). він фактично приймає різні мілісекунди, щоб зробити все. Так само, як у DOM.

У деяких випадках існує ще один суперефективний спосіб використання loop ... наприклад, для копіювання/клонування масиву

For(var i = array.length ; i > 0 ; arrayCopy [--i] = array [i] // doing stuff);

Зверніть увагу на налаштування параметрів:

  • Те саме, що й у циклі while. Я використовую лише одну змінну
  • Необхідно перевірити, чи більше індекс більше 0;
  • Як ви можете бачити, цей підхід відрізняється від звичайного циклу, який кожен використовує, оскільки я роблю матеріал всередині 3-го параметра, а також зменшую безпосередньо всередині масиву.

Сказано, що це підтверджує, що машини, такі як

писав, що я думав, щоб зробити його трохи коротше і видалити деякі непотрібні речі і написав цей, використовуючи той же стиль:

For(var i = array.length ; i-- ; arrayCopy [i] = array [i] // doing stuff);

Навіть якщо це коротше, схоже, що використання ще раз уповільнює все. Це на 1/5 повільніше за попередній цикл for і While.

Примітка: ; дуже важливо після того, як для looo без ()

Навіть якщо я тільки-но сказав вам, що jsperf - це не найкращий спосіб протестувати скрипти. Я додав тут 2 цикли.

І ось ще одна відповідь про продуктивність у javascript

Ця відповідь має показати виконавчі способи написання JavaScript. Тому, якщо ви не можете прочитати це, запитайте і ви отримаєте відповідь або прочитаєте книгу про javascript http://www.ecma-international.org/ecma-262/5.1/

Остання ревізія тесту, яку я підготував (шляхом повторного використання старішого), показує одну річ.

Довжина кешування не така важлива, але це не шкодить.

Кожен перший запуск тесту, пов'язаного вище (на вкладці, що недавно відкрилася), дає найкращі результати для останніх 4 фрагментів (3-й, 5-й, 7-й і 10-й в діаграмах) в Chrome, Opera і Firefox на моєму 64- бітному Debian Squeeze (моє настільне обладнання). Наступні прогони дають зовсім інший результат.

Висновки щодо продуктивності прості:

  • Перейдіть в цикл for (вперед) та перевірте за допомогою!== замість< .
  • Якщо вам не потрібно повторно використовувати масив пізніше, тоді також ефективний цикл із зменшеною довжиною та деструктивним масивом shift() -ing.

В даний час (2011.10) нижче шаблон виглядає як найшвидший.

For (var i = 0, len = arr.length; i !== len; i++) ( ... )

Пам'ятайте, що кешування arr.length тут не має вирішального значення, тому ви можете просто протестувати i !== arr.length , і продуктивність не знизиться, але ви отримаєте коротший код.

PS: Я знаю, що у фрагменті з shift() його результат можна використовувати замість доступу до 0-го елементу, але я чомусь забував, що після повторного використання попередньої ревізії (яка мала неправильне значення під час циклів), а пізніше я не хотів втрачати вже отримані результати.

"Найкращий", як у чистому виконанні? або продуктивність І?

Чиста продуктивність "найкраща" - це те, що використовує кеш та префіксний оператор ++ (мої дані: http://jsperf.com/caching-array-length/189)

For (var i = 0, len = myArray.length; i< len; ++i) { // blah blah }

Я б сказав, що цикл без кешу - найкращий баланс часу виконання та часу читання програміста. Кожен програміст, що починається з C/C++/Java, не витрачатиме мс, щоб прочитати цей

For(var i=0; i< arr.length; i++){ // blah blah }

** Кешуйте довжину масиву всередині циклу, деякі секунди часу будуть вислизати. Залежить від елементів у масиві, якщо в масиві є більше елементів, існує велика різниця щодо Ms часу *

SArr; // Array; for(var i = 0 ; i = 0) ( doSomething(array[i]); )

Якщо пріоритетний порядок є важливим, використовуйте цей підхід.

Let ii = array.length; let i = 0; while (i< ii) { doSomething(array[i]); ++i; }

Я завжди пишу у першому стилі.

Навіть якщо компілятор досить розумний, щоб оптимізувати його для масивів, але все ж таки він розумний, якщо ми використовуємо DOMNodeList тут або якийсь складний об'єкт з розрахованою довжиною?

Я знаю, що питання про масиви, але я вважаю гарною практикою писати всі ваші петлі в одному стилі.

Var arr =; // The array var i = 0; while (i< arr.length) { // Do something with arr[i] i++; }

i ++ швидше, ніж ++ i, --i і я -

Вітаю! Минулого уроці ми з вами розглянули що таке об'єкти і навіщо вони потрібні, а сьогодні розберемо як працювати з властивостями об'єкта і як усі ці властивості перебирати. Для цих цілей використовується цикл за властивостями for..in (почитати про цикли JavaScript можна ).

Цикл for..in

Синтаксис:

For (key in obj) ( /* ... дії з obj ... */ )

Цикл for..in послідовно перебиратиме властивості об'єкта obj, ім'я кожної властивості запише в key.

Оголошення змінної циклу for (var key in obj)

У цьому циклі можна оголосити змінну key:

For (var key in menu1) ( // ... )

Розгляньмо приклад перебору властивостей об'єкта, використовуючи цикл for…in:

Var menu = (width: 400, height: 300, title: "Menu My"); for (var key in menu) ( // цей код спрацює для кожної властивості об'єкта // ..і виведе відповідно ім'я властивості та його значення alert("Ключ: " + key + " значення: " + menu);

Хочу звернути вашу увагу на те, що в прикладі були використані квадратні дужки menu. Це тому, що якщо ім'я властивості ми зберігаємо у змінній, то й звернутися до нього можна лише через квадратні дужки, але не через точку.

Цикл for…of

Також з'явився новий цикл з обходу об'єктів та масивів. Його синтаксис дуже нагадує цикл for…in, а відмінності у тому, що він виводить не ключі чи індекси масиву, яке значення. Ось приклад:

Var menu = (width: 400, height: 300, title: "Menu My"); for (var key of menu) (// цей код спрацює для кожної властивості об'єкта //. )

Кількість властивостей в об'єкті

А якщо вам треба дізнатися кількість властивостей в об'єкті? Як це можна зробити?

На жаль, готових рішень для цього питання немає.

Найпростіший спосіб це зробити цикл за властивостями і порахувати наступним чином:

Var menu = (width: 400, height: 300, title: "Menu My"); var count = 0; for (var key in menu) ( count++; ) alert("Усього властивостей: " + count);

Підсумки
  • Для вибору властивостей об'єкта використовується цикл за ключами: for (key in obj).
Завдання Визначте, чи порожній об'єкт

Створіть функцію isEmptyObject(obj), яка повертає true, якщо в об'єкті немає властивостей та false – якщо хоч одна властивість є.

Працювати має так:

Function isEmptyObject(obj) ( /* код */ ) var obj = (); alert(isEmptyObject(obj)); // true obj["8:30"] = "підйом"; alert(isEmptyObject(obj)); // false

Підрахуйте середнє арифметичне всіх властивостей об'єкту

Є об'єкт salary із зарплатами. Напишіть код, який виведе середнє арифметичне за всіма зарплатами.
Якщо об'єкт порожній, результат має бути 0.
Наприклад.

Вітаю! Продовжуємо вивчати методи масивів і у цьому уроці розглянемо методи для перебору масиву. Ці методи дозволяють пройтися масивом і виконати певні дії над його елементами. Так забув сказати всі ці методи не підтримуються в IE 8. Хоча так це вже зараз важливо що вони не підтримуються цим браузером, але все ж якщо хочете підтримку IE8, то ES5-shim вам в допомогу. А ми продовжуватимемо

Метод forEach

Даний метод використовується для проходу масивом в циклі, але йому можна передати функцію, в якій можна робити певні дії над елементами масиву. Розглянемо з прикладу.

Var mas = ["Банан", "Авокадо", "Морква"]; mas.forEach(function(item, i, mas) ( alert(i + ": " + item + " (масив:" + mas + ")"); ));

Тут у прикладі в метод forEach передається функція в якій вказується 3 параметри:

item - елемент масиву

i - номер елемента масиву

mas - масив, що обробляється.

Даний метод можна використовувати замість циклу для перебору масиву.

Метод filter

Цей метод також як і метод forEach використовується для перебору масиву і йому передається функція як аргумент, але він дозволяє фільтрувати масив і повертає новий масив, куди потрапляють лише ті елементи для яких функція, яку ми передаємо в цей метод, поверне true.

Трохи заплутано, тож розглянемо на прикладі.

Var mas =; var positiveNum = mas.filter(function(num) ( return num > 0; )); document.write(positiveNum); // 1,4,3

У прикладі є масив із числами і нам треба отримати інший масив, в якому були б лише позитивні числа з вихідного масиву. Для цього до масиву застосовуємо метод filter і викликаємо функцію, яка перевірятиме кожен елемент, тобто вона поверне всі позитивні числа, а результат буде зберігатися в іншому масиві в прикладі це positiveNum.

Метод map

Метод map створює інший масив, який буде складатися з результатів виклику функції вихідного масиву, але в цій функції над елементами вихідного масиву відбуватимуться якісь дії і результат виявиться в новому масиві як. Давайте розберемо приклад, бо я думаю зовсім незрозуміло.

Var mas =; var newMas = mas.map(function(item) ( return item*item; )); // отримали масив із квадратами alert(newMas); // 1,4,9

У прикладі є вихідний масив з числами до нього застосовується метод map, в якому кожен елемент масиву множиться сам на себе і результат записується в інший масив. У результаті отримаємо масив із квадратами чисел вихідного масиву.

Методи every/some

Дані методи перевіряють присутній елемент у масиві. Роблять вони це через функцію, яка їм передається як параметр, тобто якщо ця функція поверне true, тоді і сам метод поверне true. Причому метод every вимагає, щоб кожен елемент відповідав умові функції, а метод some, щоб хоча б один відповідав. І як завжди ось вам приклад.

Var mas =; function isPositiv(num) ( return num > 0; ) if(mas.every(isPositiv)) ( document.write("Масив містить тільки позитивні числа"); ) else( document.write("У масиві є хоча б одне негативне число "); ) if(mas.some(isPositiv)) ( document.write("У масиві є хоча б одне позитивне число"); ) else ( document.write("У масиві немає позитивних чисел"); )

Розглянемо приклад у нас є масив із позитивними та негативними числами і нам треба перевірити його на наявність хоча б одного негативного числа. Для цього використовуємо методи every та some. Створюємо функцію, яка повертатиме позитивні числа і потім її передаємо в метод every оскільки даний метод повертає логічний результат, то використовується він в умовних операторах. Метод every у нашому прикладі поверне false тому що в масиві є негативні числа, а ось метод some поверне true, тому що в масиві є хоча б одне позитивне число.

reduce/reduceRight

Якщо вам потрібно перебрати масив – ви можете використовувати forEach, for або for..of.

Якщо вам потрібно перебрати масив і повернути дані для кожного елемента, ви використовуєте map.

Методи arr.reduce і arr.reduceRight схожі на методи вище, але вони трохи складніші. Вони використовуються для обчислення якогось одного значення на основі всього масиву.

Синтаксис:

Let value = arr.reduce(function(previousValue, item, index, array) ( // ... ), );

Функція застосовується по черзі до всіх елементів масиву і переносить свій результат на наступний виклик.

Аргументи:

  • previousValue – результат попереднього виклику цієї функції, дорівнює initial при першому виклику (якщо передано initial),
  • item – черговий елемент масиву,
  • index – його індекс,
  • Array – сам масив.

При виклику функції результат її виклику попередньому елементі масиву передається як аргумент.

Звучить складно, але все стає простіше, якщо думати про перший аргумент як результат, що «акумулює» попередніх викликів функції. Після закінчення він стає результатом зменшення.

Цей метод найпростіше зрозуміти як завжди на прикладі.

Тут ми отримаємо суму всіх елементів масиву лише одним рядком:

Let arr =; let result = arr.reduce((sum, current) => sum + current, 0); alert(result); // 15

Тут ми використовували найпоширеніший варіант reduce, який використовує лише 2 аргументи.

Давайте детальніше розберемо, як він працює.

  • При першому запуску sum дорівнює initial (останній аргумент reduce), тобто 0, а current - перший елемент масиву, що дорівнює 1. Таким чином, результат функції дорівнює 1.
  • При другому запуску sum = 1 і до нього ми додаємо другий елемент масиву (2).
  • У третьому запуску sum = 3, до якого ми додаємо наступний елемент, тощо…
  • Потік обчислень виходить такий:

    У вигляді таблиці, де кожен рядок – виклик функції на черговому елементі масиву:

    sum current result
    перший виклик 1 1
    другий виклик 1 2 3
    третій виклик 3 3 6
    четвертий виклик 6 4 10
    п'ятий виклик 10 5 15

    Тут виразно видно, як результат попереднього виклику передається до першого аргументу наступного.

    Ми також можемо опустити початкове значення:

    Let arr =; // прибрано початкове значення (немає 0 наприкінці) let result = arr.reduce((sum, current) => sum + current); alert(result); // 15

    Результат – такий самий! Це тому, що за відсутності initial як одне значення береться перший елемент масиву, а перебір стартує з другого.

    Таблиця обчислень буде такою самою за вирахуванням першого рядка.

    Але таке використання потребує надзвичайної обережності. Якщо масив є порожнім, то виклик reduce без початкового значення видасть помилку.

    Ось приклад:

    Let arr =; // Error: Reduce of empty array with no initial value // Якби існувало початкове значення, reduce повернув його для порожнього масиву. arr.reduce((sum, current) => sum + current);

    Підсумки

    Отже підіб'ємо підсумки ми розглянули різні методи для роботи з масивами в циклі у всіх цих методів є одне спільне те, що всім їм треба передавати функцію в якості аргументу.

    • forEach – для перебору масиву у циклі.
    • filter – здійснення фільтрації масиву. Повертає новий відфільтрований масив
    • every/some – для перевірки масиву щодо присутності окремих елементів.
    • map – для перетворення масиву на масив. Повертає вихідний перетворений масив.
    • reduce/reduceRight — обчислює одне значення всього масиву, викликаючи функцію кожного елемента і передаючи проміжний результат між викликами. Можна використовувати для розрахунку суми елементів масиву.
    Завдання Отримайте новий масив

    Нехай даний масив var mas = ["HTML", "CSS", "JavaScript", "Pascal"] вам треба за допомогою методу map отримати новий масив, який буде містити довжини кожного елемента вихідного масиву.

    Відфільтруйте масив

    Є масив var mas = вам потрібно, використовуючи метод filter отримати масив, який містить лише позитивні числа.

    Перевірити масив

    Є масив var mas = вам треба перевірити, чи є в масиві негативні числа і вивести результат на екран.

    Ну і на завершення невелике відео за методами для перебору масиву в циклі.

    • Переклад
    • I. Перебір реальних масивів
    • Метод forEach і споріднені методи
    • Цикл for
    • Правильне використання циклу for...in
    • Цикл for...of (неявне використання ітератора)
    • Явне використання ітератора
    • Використання способів перебору справжніх масивів
    • Перетворення на справжній масив
    • Зауваження щодо об'єктів середовища виконання
    I. Перебір реальних масивів На даний момент є три методи перебору елементів реального масиву:
  • метод Array.prototype.forEach;
  • класичний цикл for;
  • «правильно» побудований цикл for...in.
  • Крім того, незабаром, з появою нового стандарту ECMAScript 6 (ES 6), очікується ще два способи:
  • цикл for...of (неявне використання ітератора);
  • явне використання ітератора.
  • 1. Метод forEach та споріднені методи Якщо ваш проект розрахований на підтримку можливостей стандарту ECMAScript 5 (ES5), ви можете використовувати одне з його нововведень - метод forEach .

    Приклад використання:
    var a = ["a", "b", "c"]; a.forEach(function(entry) ( console.log(entry); ));
    У загальному випадку використання forEach потребує підключення бібліотеки емуляції es5-shim для браузерів, які не мають нативної підтримки цього методу. До них відносяться IE 8 і раніше версії, які до цих пір де-не-де ще використовуються.

    До переваг дляEach відноситься те, що тут не потрібно оголошувати локальні змінні для зберігання індексу та значення поточного елемента масиву, оскільки вони автоматично передаються у функцію зворотного виклику (колбек) як аргументи.

    Якщо вас турбують можливі витрати на виклик колбека для кожного елемента, не хвилюйтеся та прочитайте це.

    ForEach призначений для перебору всіх елементів масиву, але крім нього ES5 пропонує ще кілька корисних методів для перебору всіх або деяких елементів плюс виконання при цьому будь-яких дій з ними:

    • every - повертає true, якщо для кожного елемента масиву колбек повертає значення, що приводиться до true.
    • some-повертає true, якщо хоча б для одного елемента масиву колбек повертає значення, що приводиться до true.
    • filter - створює новий масив, що включає елементи вихідного масиву, для яких колбек повертає true .
    • map - створює новий масив, що складається зі значень колбеком, що обертаються.
    • reduce - зводить масив до єдиного значення, застосовуючи колбек по черзі до кожного елемента масиву, починаючи з першого (може бути корисним для обчислення суми елементів масиву та інших підсумкових функцій).
    • reduceRight – працює аналогічно reduce, але перебирає елементи у зворотному порядку.
    2. Цикл for Старий добрий for рулит:

    Var a = ["a", "b", "c"]; var index; for (index = 0; index< a.length; ++index) { console.log(a); }
    Якщо довжина масиву незмінна протягом усього циклу, а сам цикл належить критичній у плані продуктивності ділянці коду (що малоймовірно), то можна використовувати більш оптимальну версію for зі зберіганням довжини масиву:

    Var a = ["a", "b", "c"]; var index, len; for (index = 0, len = a.length; index< len; ++index) { console.log(a); }
    Теоретично цей код має виконуватися трохи швидше, ніж попередній.

    Якщо порядок перебору елементів не важливий, то можна піти ще далі в плані оптимізації та позбутися змінної для зберігання довжини масиву, змінивши порядок перебору на зворотний:

    Var a = ["a", "b", "c"]; var index; for (index = a.length - 1; index >= 0; --index) ( console.log(a); )
    Тим не менш, у сучасних движках JavaScript подібні ігри з оптимізацією зазвичай нічого не означають.

    3. Правильне використання циклу for ... in Якщо вам порадять використовувати цикл for ... in, пам'ятайте, що перебір масивів - не те, для чого він призначений. Попри поширену оману цикл for...in перебирає не індекси масиву, а перераховані властивості об'єкта.

    Тим не менш, у деяких випадках, таких як перебір розріджених масивів , for ... in може виявитися корисним, якщо тільки дотримуватися при цьому запобіжних заходів, як показано в прикладі нижче:

    // a - розріджений масив var a =; a = "a"; a = "b"; a = "c"; for (var key in a) ( if (a.hasOwnProperty(key) && /^0$|^\d*$/.test(key) && key

    Сподобалася стаття? Поділіться їй