Как перебрать массив, содержащий объекты и получить доступ к их свойствам

189

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

for (var j = 0; j < myArray.length; j++){

console.log(myArray[j]);

}

Консоль должна вызывать каждый объект в массиве, верно? Но на самом деле он отображает только первый объект. если я консольный журнал массив вне цикла, все объекты появляются, так что там определенно больше.

Во всяком случае, вот следующая проблема. Как мне получить доступ, например, к Object1.x в массиве, используя цикл?

for (var j = 0; j < myArray.length; j++){

console.log(myArray[j.x]);

}

Это возвращает «неопределенный». Снова журнал консоли вне цикла говорит мне, что все объекты имеют значения для «х». Как мне получить доступ к этим свойствам в цикле?

В другом месте мне было рекомендовано использовать отдельные массивы для каждого из свойств, но я хочу убедиться, что сначала я исчерпал этот путь.

Спасибо!

FlyingLizard
источник
2
Можете ли вы опубликовать образец вашего массива? Первый фрагмент кода кажется правильным.
Сирко
jэто число. Вы определили это в верхней части вашего цикла.
2
Может, на myArrayсамом деле это не просто массив?
techfoobar
нам нужно больше информации о том, как построен myArray
bgusach
Со всеми последующими ответами и с принятым ответом никто не объясняет, почему возникает проблема и как ее решить с помощью цикла for. #forEachработает. Но вопрос был о петле.
FreeLightman

Ответы:

341

Используйте forEach его встроенную функцию массива. Array.forEach():

yourArray.forEach(function (arrayItem) {
    var x = arrayItem.prop1 + 2;
    console.log(x);
});
Дори Зидон
источник
2
рад помочь .. Javascript становится довольно крутым .. плюс forEach намного лучше и легче читать сложные циклы ..
Дори Зидон
3
Боюсь, что forEachэто не поддерживается в IE 9. Не вините меня! Продукт моего работодателя поддерживает это!
fatCop
1
@DoryZidon: forEach не поддерживает перерыв или остановку - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Анкур Лория,
2
Обратите внимание, что важно, чтобы у вас действительно был массив. Если вы получили yourArrayчто-то подобное document.getElementsByClassName, это будет HTMLCollection, а не массив. Тогда этот вопрос может быть полезным.
J0ANMM
Примечание: forEachблокирует и не поддерживает await. for...ofЦикл будет.
PotatoFarmer
108

Некоторые случаи использования циклического перебора массива в функциональном программировании в JavaScript:

1. Просто перебрать массив

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

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

2. Проверьте, проходит ли какой-либо из элементов массива тест

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. Преобразовать в новый массив

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

Примечание. Метод map () создает новый массив с результатами вызова предоставленной функции для каждого элемента в вызывающем массиве.

4. Подведите итог конкретного свойства и рассчитайте его среднее

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. Создайте новый массив на основе оригинала, но не изменяя его

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. Подсчитайте количество каждой категории

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. Получить подмножество массива на основе определенных критериев

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

Примечание. Метод filter () создает новый массив со всеми элементами, которые проходят тест, реализованный предоставленной функцией.

8. Сортировать массив

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

введите описание изображения здесь

9. Найти элемент в массиве

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

введите описание изображения здесь

Метод Array.prototype.find () возвращает значение первого элемента в массиве, которое удовлетворяет предоставленной функции тестирования.

Ссылки

Юйцы
источник
1
Это фантастическая ссылка - оригинал этого вопроса или у вас есть что-то подобное в другом месте?
Сальваторе
Очень хорошо объяснил и подробный ответ, спасибо за помощь.
Эрика Саммерс
привет, если я хочу показать все имя и затем сделать сравнение, вы знаете, как это сделать?
dipgirl
@dipgirl, это что-то вроде ниже? const people = [ {name: "john", age:23}, {name: "john", age:43}, {name: "jim", age:101}, {name: "bob", age:67} ]; const sortByAge = people.map(p => { console.log(p.name) return p }).sort(function (p1, p2) { return p1.age - p2.age; }); console.log(sortByAge);
Юйцы
1
Поздравление за 100-й голос :)
Syed
46

Вы можете использовать цикл for..of для цикла по массиву объектов.

for (let item of items) {
    console.log(item); // Will display contents of the object inside the array
}

Одна из лучших вещей о for..of циклов состоит в том, что они могут выполнять итерации не только над массивами. Вы можете выполнять итерации любого типа, включая карты и объекты. Убедитесь, что вы используете транспортер или что-то вроде TypeScript, если вам нужно поддерживать старые браузеры.

Если вы хотите перебрать карту, синтаксис в основном такой же, как и выше, за исключением того, что он обрабатывает и ключ, и значение.

for (const [key, value] of items) {
  console.log(value);
}

Я использую for..ofциклы практически для всех видов итераций, которые я делаю в Javascript. Кроме того, одна из самых крутых вещей - они также работают с async / await.

Дуэйн Чаррингтон
источник
29
for (var j = 0; j < myArray.length; j++){
  console.log(myArray[j].x);
}
Thierry
источник
Это только решение второго вопроса.
Сирко
18

Вот пример того, как вы можете это сделать :)

var students = [{
    name: "Mike",
    track: "track-a",
    achievements: 23,
    points: 400,
  },
  {
    name: "james",
    track: "track-a",
    achievements: 2,
    points: 21,
  },
]

students.forEach(myFunction);

function myFunction(item, index) {
  for (var key in item) {
    console.log(item[key])
  }
}

Пуйи Северино
источник
Как бы вы получили значение trackсвойства для каждого элемента и присвоить его переменной для использования или интерполяции в другой части кода?
Chris22
7

Цикл массива объектов является довольно фундаментальной функциональностью. Это то, что работает для меня.

var person = [];
person[0] = {
  firstName: "John",
  lastName: "Doe",
  age: 60
};

var i, item;

for (i = 0; i < person.length; i++) {
  for (item in person[i]) {
    document.write(item + ": " + person[i][item] + "<br>");
  }
}

MangoPapa7
источник
6

myArray[j.x] логически неверно.

Используйте (myArray[j].x);вместо

for (var j = 0; j < myArray.length; j++){
  console.log(myArray[j].x);
}
Вивек Садх
источник
@ Cyborgx37 Ох .. Я имею в виду, что jx обрабатывается как имя переменной, которое неверно.
Вивек Садх
5

Это действительно просто, используя метод forEach начиная с ES5 +. Вы можете напрямую изменить каждое свойство каждого объекта в вашем массиве.

myArray.forEach(function (arrayElem){ 
  arrayElem = newPropertyValue;
});

Если вы хотите получить доступ к определенному свойству для каждого объекта:

myArray.forEach(function (arrayElem){ 
      arrayElem.nameOfYourProperty = newPropertyValue;
    });
жюльен бутелуп
источник
4

Вот еще один способ перебора массива объектов (для этого необходимо включить в документ библиотеку jQuery).

$.each(array, function(element) {
  // do some operations with each element... 
});
Партха Рой
источник
1
В вашем ответе отсутствует критическая информация о необходимости загрузки библиотеки jQuery для использования $.eachметода.
Мэтью Морек
4

Это будет работать. Цикл массива (yourArray). Затем переберите прямые свойства каждого объекта (eachObj).

yourArray.forEach( function (eachObj){
    for (var key in eachObj) {
        if (eachObj.hasOwnProperty(key)){
           console.log(key,eachObj[key]);
        }
    }
});
sangamkumar91
источник
2

Итерация объекта массива с использованием jQuery (используйте второй параметр для печати строки).

$.each(array, function(index, item) {
       console.log(index, item);
});
РС
источник
2

var c = {
    myProperty: [
        { name: 'this' },
        { name: 'can' },
        { name: 'get' },
        { name: 'crazy' }
    ]
};

c.myProperty.forEach(function(myProperty_element) {
    var x = myProperty_element.name;
    console.log('the name of the member is : ' + x);
})

Это один из способов, как мне удалось этого добиться.

Гурунат Рао
источник
1

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

  yourArray.forEach(arrayItem => {
      var x = arrayItem.prop1 + 2;
      console.log(x);
  });

Также в $ .each вы можете использовать функцию стрелки, как показано ниже

 $.each(array, (item, index) => {
       console.log(index, item);
 });
Хемадри Дасари
источник
1

const jobs = [
    {
        name: "sipher",
        family: "sipherplus",
        job: "Devops"
    },
    {
        name: "john",
        family: "Doe",
        job: "Devops"
    },
    {
        name: "jim",
        family: "smith",
        job: "Devops"
    }
];

const txt = 
   ` <ul>
        ${jobs.map(job => `<li>${job.name} ${job.family} -> ${job.job}</li>`).join('')}
    </ul>`
;

document.body.innerHTML = txt;

Будь осторожен со спиной Клещи (`)

sipher
источник
0

Это может кому-то помочь. Может быть, это ошибка в Node.

var arr = [ { name: 'a' }, { name: 'b' }, { name: 'c' } ];
var c = 0;

Это не работает:

while (arr[c].name) { c++; } // TypeError: Cannot read property 'name' of undefined

Но это работает ...

while (arr[c]) { c++; } // Inside the loop arr[c].name works as expected.

Это тоже работает ...

while ((arr[c]) && (arr[c].name)) { c++; }

НО просто изменение порядка не работает. Я предполагаю, что здесь есть какая-то внутренняя оптимизация, которая ломает Node.

while ((arr[c].name) && (arr[c])) { c++; }

Ошибка говорит, что массив не определен, но это не так: - / Node v11.15.0

Пи Джей Брюнет
источник