Как я могу перебрать все записи в массиве, используя JavaScript?

Я думал, что это было что-то вроде этого:

forEach(instance in theArray)

Где theArray - мой массив, но, похоже, это неверно.

5233
Dante1986 17 Фев 2012 в 17:51

24 ответа

Если у вас огромный массив, вы должны использовать {{X0 }} , чтобы повысить эффективность. Итераторы являются свойством некоторых коллекций JavaScript (например, {{X1 }}, Set , String, < a href = "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" rel = "noreferrer"> Array ). Даже {{X5} } использует iterator под капотом.

Итераторы повышают эффективность, позволяя вам использовать элементы списка по одному, как если бы они были потоком. Что делает итератор особенным, так это то, как он пересекает коллекцию. Другие циклы должны загружать всю коллекцию заранее, чтобы выполнить итерацию, тогда как итератору нужно знать только текущую позицию в коллекции.

Вы получаете доступ к текущему элементу, вызывая метод next итератора. Следующий метод вернет value текущего элемента и boolean , чтобы указать, когда вы достигли конца коллекции. Ниже приведен пример создания итератора из массива.

Преобразуйте свой обычный массив в итератор, используя {{X0} } метод такой:

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Вы также можете преобразовать свой обычный массив в итератор, используя { {X0}} вот так:

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Вы также можете преобразовать свой обычный array в {{ X1}} вот так:

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

ПРИМЕЧАНИЕ :

  • Итераторы носят исчерпывающий характер.
  • Объекты не являются iterable по умолчанию. Используйте for..in в таком случае, потому что вместо значений он работает с ключами.

Вы можете прочитать больше о iteration protocol здесь,

5
BlackBeard 6 Июл 2018 в 11:32

Наиболее близким к вашей идее было бы использовать Array.forEach(), который принимает функцию замыкания, которая будет выполняться для каждого элемента массива.

myArray.forEach(
  (item) => {
    // Do something
    console.log(item);
  }
);

Другим жизнеспособным способом было бы использовать Array.map(), который работает таким же образом, но он также принимает все возвращаемые вами значения и возвращает их в новом массиве (по сути, отображая каждый элемент в новый), например так:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
7
CherryDT 4 Сен 2019 в 17:51

ECMAScript 5 (версия на JavaScript) для работы с массивами:

forEach - выполняет итерацию по каждому элементу в массиве и делает с каждым элементом все, что вам нужно.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is #" + (index+1) + " in the musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

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

map - создает новый массив с результатом функции обратного вызова. Этот метод хорошо использовать, когда вам нужно отформатировать элементы вашего массива.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

reduce . Как следует из названия, массив сводится к одному значению, вызывая данную функцию, передавая текущий элемент и результат предыдущего выполнения.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - возвращает значение true или false, если все элементы массива проходят тест в функции обратного вызова.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
  return elem >= 18;
});

// Output: false

фильтр - очень похоже на все, за исключением того, что фильтр возвращает массив с элементами, которые возвращают значение true для данной функции.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]
18
Peter Mortensen 3 Сен 2019 в 20:55

Если вы хотите использовать forEach(), это будет выглядеть как -

theArray.forEach ( element => {
    console.log(element);
});

Если вы хотите использовать for(), это будет выглядеть как -

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}
5
cfnerd 4 Янв 2019 в 23:18

JQuery способ, используя $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];
11
Daniel W. 1 Апр 2014 в 11:15

Вероятно, цикл for(i = 0; i < array.length; i++) не лучший выбор. Почему? Если у вас есть это:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

Метод будет вызываться из array[0] в array[2]. Во-первых, это будет сначала ссылаться на переменные, которых у вас даже нет, во-вторых, у вас не будет переменных в массиве, и в-третьих, это сделает код более смелым. Посмотрите здесь, это то, что я использую:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

И если вы хотите, чтобы это была функция, вы можете сделать это:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

Если вы хотите сломаться, немного больше логики:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

Примере:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

Он возвращает:

//Hello
//World
//!!!
27
Peter Mortensen 8 Мар 2014 в 10:49

Если вы хотите перебрать массив объектов с помощью функции стрелки:

let arr = [{name:'john', age:50}, {name:'clark', age:19}, {name:'mohan', age:26}];

arr.forEach((person)=>{
  console.log('I am ' + person.name + ' and I am ' + person.age + ' old');
})
6
Peter Mortensen 3 Сен 2019 в 20:04

Согласно новой обновленной функции ECMAScript 6 (ES6) и ECMAScript 2015, вы можете использовать следующие параметры с циклами:

для циклов

for(var i = 0; i < 5; i++){
  console.log(i);
}

// Output: 0,1,2,3,4

для ... в циклах

let obj = {"a":1, "b":2}

for(let k in obj){
  console.log(k)
}

// Output: a,b

< Сильный > Array.forEach ( )

let array = [1,2,3,4]

array.forEach((x) => {
  console.log(x);
})

// Output: 1,2,3,4

для ... циклов

let array = [1,2,3,4]

for(let x of array){
  console.log(x);
}

// Output: 1,2,3,4

циклы while

let x = 0

while(x < 5){
  console.log(x)
  x++
}

// Output: 1,2,3,4

делай ... пока цикл

let x = 0

do{
  console.log(x)
  x++
}while(x < 5)

// Output: 1,2,3,4
4
Peter Mortensen 8 Мар 2020 в 14:51

Начиная с ECMAScript 6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

Где of избегает странностей, связанных с in, и заставляет его работать как цикл for любого другого языка, а let связывает i внутри цикла в противоположность с точностью до функции.

Скобки ({}) могут быть опущены, когда есть только одна команда (например, в примере выше).

28
Peter Mortensen 12 Сен 2019 в 05:12

Вы можете позвонить forEach, как это:

forEach будет выполнять итерацию по предоставленному вами массиву, и для каждой итерации он будет иметь element, который содержит значение этой итерации. Если вам нужен индекс, вы можете получить текущий индекс, передав i в качестве второго параметра в функцию обратного вызова для forEach.

Foreach - это в основном функция высокого порядка, которая принимает в качестве параметра другую функцию.

let theArray= [1,3,2];

theArray.forEach((element) => {
  // Use the element of the array
  console.log(element)
}

Выход:

1
3
2

Вы также можете перебрать массив так:

for (let i=0; i<theArray.length; i++) {
  console.log(i); // i will have the value of each index
}
7
Nouman Dilshad 25 Янв 2020 в 12:13

В нативном JavaScript нет цикла for each. Вы можете использовать библиотеки для получения этой функциональности (я рекомендую Underscore.js) использовать простой for в цикле.

for (var instance in objects) {
   ...
}

Однако обратите внимание, что могут быть причины использовать еще более простой цикл for (см. Вопрос о переполнении стека Почему используется «для ... в "с итерацией массива такая плохая идея? )

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
22
Community 23 Май 2017 в 11:47

Это итератор для не разреженного списка, где индекс начинается с 0, что является типичным сценарием при работе с document.getElementsByTagName или document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Примеры использования:

Пример № 1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

Пример № 2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Каждый тег p получает class="blue"

Пример № 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Каждый второй тег p получает class="red">

Пример № 4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

И, наконец, первые 20 синих p-тегов заменены на зеленые.

Предостережение при использовании строки как функции: функция создается вне контекста и должна использоваться только в том случае, если вы уверены в области видимости переменной. В противном случае лучше передавать функции там, где обзор более интуитивно понятен.

21
Karl Gjertsen 29 Сен 2016 в 12:28

Если вы не против очистки массива:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x будет содержать последнее значение y и будет удалено из массива. Вы также можете использовать shift(), который даст и удалит первый элемент из y.

33
joeytwiddle 30 Май 2014 в 18:37

Нет встроенной способности проникнуть в forEach. Чтобы прервать выполнение, используйте Array#some, как показано ниже:

[1,2,3].some(function(number) {
    return number === 1;
});

Это работает, потому что some возвращает true, как только любой из обратных вызовов, выполненных в порядке массива, возвращает true, замыкая выполнение остальных. Оригинальный ответ см. прототип Array для некоторых

15
Community 23 Май 2017 в 12:34

Если вы используете jQuery библиотеку, вы можете использовать jQuery.each :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

РЕДАКТИРОВАТЬ:

Что касается вопроса, пользователь хочет код в javascript вместо jquery, поэтому редактирование

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
237
Anik Islam Abhi 12 Ноя 2015 в 05:17

Использование циклов с ECMAScript 6 деструктуризация и оператор распространения

Разрушение и использование оператора распространения оказалось весьма полезным для новичков в ECMAScript 6 как более удобочитаемый / эстетичный, хотя некоторые ветераны JavaScript могут посчитать это грязным. Юниоры или другие люди могут найти это полезным.

В следующих примерах будет использоваться {{ X0}} и {{ X1}} метод.

Примеры 6, 7 и 8 можно использовать с любыми функциональными циклами, такими как .map, .filter, .reduce, .sort, {{X4} }, .some. Дополнительную информацию об этих методах можно найти в объекте Array..

Пример 1: нормальный цикл for...of - здесь никаких хитростей.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

Пример 2: разделение слов на символы

let arrFruits = ['apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);
}

Пример 3: цикл с key и value

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type:
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on Internet Explorer  unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

Пример 4: получить свойства объекта встроенными

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

Пример 5 . Получите необходимые свойства объекта

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

Пример 6 . Используется ли Пример 3 с .forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

Пример 7 . Используется ли Пример 4 с .forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions
// are required to be surrounded by parentheses
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

Пример 8 . Используется ли Пример 5 с .forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});
9
Peter Mortensen 3 Сен 2019 в 20:21

Лямбда-синтаксис обычно не работает в Internet Explorer 10 или ниже.

Я обычно использую

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

Если вы являетесь jQuery fan и у вас уже запущен файл jQuery, вам следует поменять местами позиции индекса и значения параметров

$("#ul>li").each(function(**index, value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
6
Peter Mortensen 3 Сен 2019 в 20:36

Если вы хотите зациклить массив, используйте стандартный трехчастный цикл for.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

Вы можете добиться некоторой оптимизации производительности, кэшируя myArray.length или повторяя ее в обратном порядке.

42
Quentin 17 Фев 2012 в 13:55

Примечание . Этот ответ безнадежно устарел. Для более современного подхода посмотрите методы, доступные в массив. Интересующие методы могут быть:

  • для каждого
  • карта
  • фильтр
  • застегивать
  • уменьшить
  • каждый
  • некоторые

Стандартный способ перебора массива в JavaScript - это простой for - цикл:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

Обратите внимание, однако, что этот подход хорош, только если у вас плотный массив, и каждый индекс занят элементом. Если массив разреженный, то при таком подходе вы можете столкнуться с проблемами производительности, так как вы будете перебирать множество индексов, которые действительно не существуют в массиве. В этом случае цикл for .. in может быть лучшей идеей. Однако , вы должны использовать соответствующие меры предосторожности, чтобы гарантировать, что будут действовать только требуемые свойства массива (то есть элементы массива), поскольку цикл for..in - также будет перечисляться в устаревших браузерах или если дополнительные свойства определены как enumerable.

В ECMAScript 5 будет присутствовать метод forEach в прототипе массива, но это не поддерживается в устаревших браузерах. Поэтому, чтобы иметь возможность использовать его последовательно, у вас должна быть среда, которая его поддерживает (например, узел. js для серверного JavaScript) или используйте «Polyfill». Polyfill для этой функциональности, однако, тривиален, и, поскольку он делает код более легким для чтения, его стоит включить в Polyfill.

506
Peter Mortensen 3 Сен 2019 в 19:57

Я также хотел бы добавить это как композицию обратного цикла и ответ выше для кого-то, кто также хотел бы этот синтаксис.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Плюсы:

Преимущество для этого: у вас есть ссылка уже в первом, как это не нужно будет объявить позже с другой строкой. Это удобно при зацикливании через массив объектов.

Минусы:

Это будет прерываться всякий раз, когда ссылка ложная - ложная (неопределенная и т. Д.). Однако это можно использовать как преимущество. Тем не менее, это затруднило бы чтение. А также в зависимости от браузера он может быть «не» оптимизирован для работы быстрее оригинального.

12
HZStudio 28 Мар 2020 в 16:08

Некоторые языки C стиля используют foreach для циклического перебора перечислений. В JavaScript это делается с помощью for..in структуры цикла :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

Есть подвох. for..in будет перебирать каждый из перечисляемых членов объекта и членов его прототипа. Чтобы избежать чтения значений, которые наследуются через прототип объекта, просто проверьте, принадлежит ли свойство объекту:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Кроме того, ECMAScript 5 добавил forEach метод Array.prototype, который можно использовать для перечисления по массиву с помощью Calback (полифилл находится в документации, так что вы можете использовать его для старых браузеров):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

Важно отметить, что Array.prototype.forEach не прерывается, когда обратный вызов возвращает false. jQuery и Underscore.js предоставляют свои собственные варианты each для создания циклов, которые могут быть закорочены.

83
Peter Mortensen 13 Июл 2013 в 01:18

Существует несколько способов перебрать массив в JavaScript, как показано ниже:

для - это самый распространенный . Полный блок кода для зацикливания

var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

while - цикл пока условие выполнено. Вроде бы самая быстрая петля

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do / while - также циклически перебирает блок кода, пока условие выполнено, будет выполняться как минимум один раз

var text = ""
var i = 0;

do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);

document.getElementById("example").innerHTML = text;
<p id="example"></p>

Функциональные циклы - forEach, map, filter, а также reduce (они циклически перебирают функцию, но используются, если вам нужно что-то с вашим массивом и т. д.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

Для получения дополнительной информации и примеров о функциональном программировании массивов, посмотрите сообщение в блоге Функциональное программирование в JavaScript: отображение, фильтрация и уменьшение .

20
Alireza 22 Окт 2019 в 23:32

forEach (см. В jsFiddle):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);
31
nmoliveira 18 Дек 2013 в 12:22

Существует три реализации foreach в jQuery следующим образом.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
28
Peter Mortensen 8 Мар 2014 в 10:50