Как я могу перебрать все записи в массиве, используя JavaScript?
Я думал, что это было что-то вроде этого:
forEach(instance in theArray)
Где theArray
- мой массив, но, похоже, это неверно.
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
здесь,
Наиболее близким к вашей идее было бы использовать 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]
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]
Если вы хотите использовать forEach()
, это будет выглядеть как -
theArray.forEach ( element => {
console.log(element);
});
Если вы хотите использовать for()
, это будет выглядеть как -
for(let idx = 0; idx < theArray.length; idx++){
let element = theArray[idx];
console.log(element);
}
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];
Вероятно, цикл 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
//!!!
Если вы хотите перебрать массив объектов с помощью функции стрелки:
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');
})
Согласно новой обновленной функции 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
Начиная с ECMAScript 6:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
Где of
избегает странностей, связанных с in
, и заставляет его работать как цикл for
любого другого языка, а let
связывает i
внутри цикла в противоположность с точностью до функции.
Скобки ({}
) могут быть опущены, когда есть только одна команда (например, в примере выше).
Вы можете позвонить 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
}
В нативном 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];
...
}
Это итератор для не разреженного списка, где индекс начинается с 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-тегов заменены на зеленые.
Предостережение при использовании строки как функции: функция создается вне контекста и должна использоваться только в том случае, если вы уверены в области видимости переменной. В противном случае лучше передавать функции там, где обзор более интуитивно понятен.
Если вы не против очистки массива:
var x;
while(x = y.pop()){
alert(x); //do something
}
x
будет содержать последнее значение y
и будет удалено из массива. Вы также можете использовать shift()
, который даст и удалит первый элемент из y
.
Нет встроенной способности проникнуть в forEach
. Чтобы прервать выполнение, используйте Array#some
, как показано ниже:
[1,2,3].some(function(number) {
return number === 1;
});
Это работает, потому что some
возвращает true, как только любой из обратных вызовов, выполненных в порядке массива, возвращает true, замыкая выполнение остальных. Оригинальный ответ см. прототип Array для некоторых
Если вы используете 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].
}
Использование циклов с 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);
});
Лямбда-синтаксис обычно не работает в 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);
});
Если вы хотите зациклить массив, используйте стандартный трехчастный цикл for
.
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
Вы можете добиться некоторой оптимизации производительности, кэшируя myArray.length
или повторяя ее в обратном порядке.
Примечание . Этот ответ безнадежно устарел. Для более современного подхода посмотрите методы, доступные в массив. Интересующие методы могут быть:
- для каждого
- карта
- фильтр
- застегивать
- уменьшить
- каждый
- некоторые
Стандартный способ перебора массива в 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.
Я также хотел бы добавить это как композицию обратного цикла и ответ выше для кого-то, кто также хотел бы этот синтаксис.
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
console.log(item);
}
Плюсы:
Преимущество для этого: у вас есть ссылка уже в первом, как это не нужно будет объявить позже с другой строкой. Это удобно при зацикливании через массив объектов.
Минусы:
Это будет прерываться всякий раз, когда ссылка ложная - ложная (неопределенная и т. Д.). Однако это можно использовать как преимущество. Тем не менее, это затруднило бы чтение. А также в зависимости от браузера он может быть «не» оптимизирован для работы быстрее оригинального.
Некоторые языки 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
для создания циклов, которые могут быть закорочены.
Существует несколько способов перебрать массив в 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: отображение, фильтрация и уменьшение .
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
}
);
Существует три реализации 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
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Имейте в виду, что JavaScript — это НЕ то же самое, что Java! Включите все ярлыки, относящиеся к вашему вопросу; например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [svelte] и т. д.